为什么在原型中定义了实例方法,但在构造函数中定义了实例字段?

Dav*_*tey 3 javascript

在JavaScript中进行继承时,我总是看到的模式定义了原型中的实例方法,但是构造函数中的实例字段(参见下面的示例).这是什么动机?为什么不在原型中保持一致并定义两者?

function MyClass() {
    this.myField = 0; // why this...
}
MyClass.prototype.myField = 0; // ...instead of this?
Run Code Online (Sandbox Code Playgroud)

Fel*_*ing 12

说明

因为原型属性在所有实例之间共享,因为每个实例都具有对同一原型对象的引用.

这不是不可变类型的问题,您可以这样做:

MyClass.prototype.myField = 0;

var a = new MyClass();
a.myField = 42;
Run Code Online (Sandbox Code Playgroud)

并且只有a这个价值.这是因为赋值myField为其创建了属性a.您可以a.hasOwnProperty('myField')在分配之前和之后通过调用来测试它.

但是如果你有对象或数组

MyClass.prototype.myField = [];
Run Code Online (Sandbox Code Playgroud)

并且您只是附加到该数组并且不分配新数组(如a.myField = []),然后每个实例在该数组中都有新值.


您必须在构造函数中初始化数组和对象,以便每个实例都获得自己的对象或数组实例.一些样式指南建议你仍然在原型上创建属性,但是用它初始化它null.除了在代码中添加一些概念结构(如果存在这样的单词)之外,这没有任何好处.

例如:

function MyClass() {
    this.myField = [];
}

/**
 * @type {Array}
 */
MyClass.prototype.myField = null;
Run Code Online (Sandbox Code Playgroud)

  • 所以,听起来你说如果你想要为每个实例提供相同的**,你可以在原型上设置它.如果你想在每个实例上允许某些东西****,你可以在实例上定义它.并且,请注意,您希望每个实例的方法都相同(因此您将它们分配给原型)并且您希望允许每个实例的数据不同,因此您可以在实例中分配它们(通常在构造函数中) ) (3认同)