Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何用JavaScript创建类?_Javascript_Json - Fatal编程技术网

如何用JavaScript创建类?

如何用JavaScript创建类?,javascript,json,Javascript,Json,在JavaScript中有很多方法可以做同样的事情。然而,我学会了一些方法,有些方法我真的不明白。有人能帮我澄清一些事情吗?(我第一次在PHP中学习OOP。) 因此,可以这样创建一个类: var object = new class(constructparams) { var private_members; // Can be accessed from within the code inside this definition only. this.public_memb

在JavaScript中有很多方法可以做同样的事情。然而,我学会了一些方法,有些方法我真的不明白。有人能帮我澄清一些事情吗?(我第一次在PHP中学习OOP。)

因此,可以这样创建一个类:

var object = new class(constructparams) {
    var private_members; // Can be accessed from within the code inside this definition only.
    this.public_members; // Can be accessed from everywhere.

    var private_functions = function() {}
    this.public_functions = function() {}
}

object.prototype.semi_public_members = function() {
    // Will be public, but can only access public members and methods.
    // E. g. private_members; is not available here.
}
到目前为止,这些都正确吗

然后有人喜欢使用自动执行的匿名函数方法来创建名称空间。这有什么意义呢,当你用上面的方法做同样的事情时,提供了一个名称空间

最后是我不懂的对象文字符号

var object = { // Something strange in here }

里面发生了什么事?是JSON吗?怎么用,怎么用。使用这种方式而不是使用我描述的方法有什么好处?为什么你要做原型而不是第一次正确地创建类?

不,那是不正确的。构造函数应与对象的创建分开:

function myClass(constructparam1) {
  this.public_member = constructparam1; // Can be accessed from everywhere.
}
方法应该在构造函数的原型中,而不是在实例中:

myClass.prototype.semi_public_members = function() {
  // Will be public
}
var obj = new myClass(1337);
使用
new
关键字调用构造函数以创建实例:

myClass.prototype.semi_public_members = function() {
  // Will be public
}
var obj = new myClass(1337);
构造函数内的局部变量只能在该函数内访问。如果类中没有局部变量,则需要在其周围使用函数来创建闭包,以便原型中的方法可以访问变量:

var myClass = (function(){

  var local_variable;

  function constructor(constructparam1) {
    this.public_member = constructparam1; // Can be accessed from everywhere.
  }

  constructor.prototype.semi_public_members = function() {
    // Will be public
    alert(local_variable); // can access private variables
  }

  return constructor;
})();
对象文字只是一种简单但有限的一次性创建对象的方法。它们没有原型,因此如果希望它们具有方法,则必须将它们指定给属性:

var obj = {

  public_member: 1337,

  semi_public_members: function(){
    alert(this.public_member);
  }

};

我认为有些概念似乎缺失了,但我会尽可能多地回答

所以一个类可以这样做…到目前为止都正确吗

这很接近,但并不完全正确。创建构造函数不需要
new
,只需要在创建“类”的新实例时使用它

然后有人喜欢自动执行的匿名函数。。。是什么 重点是

模块模式(或自执行函数)方法有点不同,因为您通常不处理原型,尽管您可以。它只是一个返回带有属性和方法的文本对象的函数,但我主要用于不需要该对象实例的单例:

var Singleton = (function() {
  var private = 'foo';
  var public = 'baz';
  var publicMethod = function() { ... }
  // Expose public methods and properties
  return {
    public: public
    publicMethod: publicMethod
  }
}());
最后是我没有的对象文字符号 明白

var object = { // Something strange in here }
这只是JavaScript中的一个常规对象,类似于PHP所称的“关联数组”。文字对象语法是JSON的基础,但JSON在格式方面有更多的限制;JavaScript更加宽容,因此您可以使用无引号的属性和方法

为什么要创建原型,而不是使类正确地 第一次


这里的要点是要理解JavaScript不是传统的面向对象语言,因此没有类,您不应该考虑类。但是原型非常强大,我认为比类更强大。网上有很多关于如何使用原型复制类的示例,但不是相反。

通过示例解释构造对象中不同事物的行为:

// Defined as a variable from an anonymous function
// so that there is scope closure over variables
// shared across all instances and the prototype.
// If this isn't important, you don't need to close
// scope around it, so define directly
var ConstructedObject = (function constructorCreator () {
    // Define any variables/methods to be shared across
    // all instances but not polluting the namespace
    var sharedVariable = 'foo';

    // Next the actual constructor
    function ConstructedObject () {
        // Variables here are normally used to help
        // each instance and will be kept in memory as
        // long as the instance exists
        var instanceVariable = 'bar';
        // instance-specific properties get defined
        // using the "this" keyword, these are the
        // properties expected to be changed across
        // each different instance
        this.instanceProperty = true;
        this.instanceMethod = function () { return instanceVariable; };
        this.changeInstanceVar = function () { instanceVariable = 'foo'; };
            // you do have access to the shared
            // variables here if you need them.
    }
    // After the constructor, you set up the
    // prototype, if any. This is an object of shared
    // properties and methods to be inherited by every
    // instance made by the constructor, and it also
    // inherits the prototype's prototype, too.
    // Lets use a literal object for simplicity.
    ConstructedObject.prototype = {
        // Accessing the instance to which a method
        // applies is done using the "this" keyword,
        // similar to in the constructor
        sharedMethod : function () { return [sharedVariable, this.instanceMethod(),this.instanceProperty]; },
        changeSharedVar : function () { sharedVariable = 'bar'; }
        // properties may also be defined
    };
    // Finally, the constructor is returned so it
    // can be kept alive outside of the anonymous
    // function used to create it
    return ConstructedObject;
// and the anonymous function is called to execute
// what we've done so far
})();
在执行上述代码之后,您就有了一个构造函数,它可以创建具有实例特定变量和共享变量的对象。现在,让我们通过创建两个实例并在一些更改之前和之后比较它们来了解它们的行为

// First create the two instances
var myObjA = new ConstructedObject(),
    myObjB = new ConstructedObject();
// Now compare them, the sharedMethod method we
// used in the prototype offers an easy way to
// do this
console.log( myObjA.sharedMethod(), myObjB.sharedMethod() );
// ["foo", "bar", true] ["foo", "bar", true]
// Next lets change the different variables in
// myObjB so we can see what happens, again the
// change* methods defined before let us do this
// easily
myObjB.changeInstanceVar();
myObjB.changeSharedVar();
// For completeness, lets also change the property
// on myObjB.
myObjB.instanceProperty = false;
// Now when we compare them again, we see that our
// changes to the myObjB instance have only changed
// the shared variables of myObjA
console.log( myObjA.sharedMethod(), myObjB.sharedMethod() );
// ["bar", "bar", true] ["bar", "foo", false]
以下是两条记录的语句,以便于查看

//     myObjA               myObjB
["foo", "bar", true] ["foo", "bar", true]
["bar", "bar", true] ["bar", "foo", false]

从技术上讲,JavaScript没有类。然而,人们经常像使用对象一样使用对象。你的最后一个例子是一个对象文本的赋值。我刚刚做了一个快捷方式:PHmm,你基本上是说原型是静态成员?而Klass()只是一个不起作用的对象,因为构造函数还没有在它上面运行来填充数据?因此,如果你有一个Klass(),它的方法可以提醒某些东西,那么它在没有实例化的情况下就可以工作了?我喜欢OOP的方法,因为它不会污染全局名称空间,而且它将事物分成模块,迫使你保持事物的条理化和非意大利面化。你将如何概述结构?如果您需要多个实例,请使用我的方法;如果您需要一个实例,请使用原型?是的,我认为它们与静态成员类似
Klass
可以是函数,也可以是构造函数,这取决于您如何调用它。如果您使用
new
则它是一个构造函数,否则它是一个函数,这就是为什么建议始终将构造函数大写以避免这种混淆。如果您想运行一个方法,您需要一个实例。因此,在上一个示例中,{}中的内容就像做原型一样?在上面的示例中,您是否在最终公开的闭包中“生成”了一个名为构造函数的对象,这样您就可以拥有一个对象,并且仍然可以访问私有成员?@StudentofHogwarts:这与使用原型类似,但方法是对象本身的成员,而不是原型的成员。如果创建多个函数对象,则每个实例都将有自己的函数对象副本,而不是共享它们。在上面的示例中,
constructor
是从封闭函数返回的,因此变量
myClass
包含构造函数,并且可以像第一个示例中一样使用。如果您创建多个实例,它们将共享局部变量,因此这可能不是如何实现这一点的最佳示例。感谢您的回复!这是一个非常可靠的答案。但我想问,为什么人们会使用这种方法,而不是使用我在示例中使用的方法?在我看来,它们都提供相同的功能。这是不是占用更少的内存?我假设你说的是整个过程都被封装在一个匿名函数中?在第一个评论中,我试图解释这一点;它是创造