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

Javascript 为什么原型中定义了实例方法,而构造函数中定义了实例字段?,javascript,Javascript,在JavaScript中执行继承时,我经常看到的模式在原型中定义实例方法,但在构造函数中定义实例字段(参见下面的示例)。这样做的动机是什么?为什么不在原型中保持一致并定义两者 function MyClass() { this.myField = 0; // why this... } MyClass.prototype.myField = 0; // ...instead of this? 解释 因为原型属性在所有实例之间共享,因为每个实例都引用同一个原型对象 这不是不可变类型的问题

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

function MyClass() {
    this.myField = 0; // why this...
}
MyClass.prototype.myField = 0; // ...instead of this?
解释 因为原型属性在所有实例之间共享,因为每个实例都引用同一个原型对象

这不是不可变类型的问题,您可以执行以下操作:

MyClass.prototype.myField = 0;

var a = new MyClass();
a.myField = 42;
只有
a
才会有这个值。这是因为分配为
a
创建了属性
myField
。您可以在赋值前后调用
a.hasOwnProperty('myField')
来测试这一点

但是如果你有对象或数组

MyClass.prototype.myField = [];
您只需附加到该数组,而不分配新数组(如
a.myField=[]
),那么每个实例在该数组中都有新值


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

例如:

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

/**
 * @type {Array}
 */
MyClass.prototype.myField = null;

啊,这是有道理的。非常感谢。所以,听起来好像你在说,如果你想让每个实例都一样,你就在原型上设置它。如果希望允许某些内容在每个实例上都不同,那么可以在实例上定义它。而且,瞧,您希望每个实例的方法都相同(因此您将它们分配给原型),并且您希望每个实例的数据都不同,因此您在实例中分配它们(通常在构造函数中)。谢谢您的解释,我绝望地试图弄明白为什么我的原型数组共享值,而我的原型字段不共享值。我现在正在为我的对象在构造函数中创建新数组。@Brian:欢迎光临!确切地说,您必须在构造函数中初始化数组,然后。。。我应该加上这个来回答,谢谢!通常在构造函数中定义一个属性,而不是在原型中定义一个属性,为每个实例提供一个返回object.hasOwnProperty(propname)true的属性。