在JavaScript中进行继承时,我总是看到的模式定义了原型中的实例方法,但是构造函数中的实例字段(参见下面的示例)。这是什么动机?为什么不在原型中保持一致并定义两者?
function MyClass() {
this.myField = 0; // why this...
}
MyClass.prototype.myField = 0; // ...instead of this?
答案 0 :(得分:12)
因为原型属性在所有实例之间共享,因为每个实例都有对同一原型对象的引用。
这不是不可变类型的问题,您可以这样做:
MyClass.prototype.myField = 0;
var a = new MyClass();
a.myField = 42;
并且只有a
才有此值。这是因为作业为myField
创建了属性a
。您可以在分配前后调用a.hasOwnProperty('myField')
进行测试。
但是如果你有对象或数组
MyClass.prototype.myField = [];
并且您只是附加到该数组并且不分配新数组(如a.myField = []
),然后每个实例在该数组中都有新值。
您必须在构造函数中初始化数组和对象,以便每个实例都获得自己的对象或数组实例。一些样式指南建议您仍然在原型上创建属性,但使用null
初始化它。除了在代码中添加一些概念结构(如果存在这样的单词)之外,这没有任何好处。
例如:
function MyClass() {
this.myField = [];
}
/**
* @type {Array}
*/
MyClass.prototype.myField = null;