我得到一个意想不到的结果与以下代码:
var TestModel,u,u2; function TestModel() {} TestModel.prototype.a = null; TestModel.prototype.b = []; u = new TestModel(); u.a = 1; u.b.push(1); u2 = new TestModel(); u2.a = 2; u2.b.push(2); console.log(u.a,u.b); // outputs: 1 [1,2] console.log(u2.a,u2.b); // outputs: 2 [1,2]
我发现令人惊讶的是,u.b和u2.b包含相同的值,即使TestModel的每个实例都应该有自己的实例变量,根据我如何设置原型.所以这是我期待的输出:
console.log(u.a,u.b); // expecting: 1 [1] console.log(u2.a,u2.b); // expecting: 2 [2]
如果我将b设置为对象并在其上设置键而不是将其用作数组,则会发生同样的情况.我在这里不了解什么?
解决方法
分配值和引用它们之间有区别.
u.a = 1;
将在u所引用的对象上创建一个新的属性.在分配之前,u.a将引用TestModel.prototype.a,但分配一个新值实际上会在实际对象上创建一个新属性:
分配后:
另一方面,
u.b.push(1);
不会创建新的财产.它将引用现有的属性,数组,即TestModel.prototype.b.
even though each instance of
TestModel
should have its own instance variables according to how I’ve setup the prototype
所有实例引用相同的原型,因此它们引用原型具有的相同属性.你可以很容易地看到,因为TestMode.prototype === u.b,TestMode.prototype === u2.b和u.b === u2.b都是true.
如果你也为u.b和u2.b分配一个新的值,它将会起作用:
u.b = [];
这通常在构造函数中完成:
function TestModel() { this.b = []; }