考虑以下代码
Class = function()
{
//this.array = [];
}
Class.prototype.array = [];
Class.prototype.str = null;
var a = new Class();
var b = new Class();
a.array.push("a");
console.log (a.array);
b.array.push("b");
console.log (b.array);
a.str = "a";
console.log (a.str);
console.log (b.str);
b.str = "b";
console.log (a.str);
console.log (b.str);
如果我们按原样运行它,我们会注意到在其任何实例中修改Class array
都是静态完成的 - a
中对数组的更改会反映在b
中反之亦然。但是,修改str
变量虽然以与array
相同的方式初始化,但不是静态完成的。
如果我们取消对构造函数中的行的注释,那么在任何实例中对数组的更改都不再是静态的。
我偶然发现了一个nodejs错误吗?我无法在任何地方找到有关这种情况的详细信息,所以有人可以解释为什么nodejs有这种行为吗?
答案 0 :(得分:3)
对象属性的分配(直接到对象属性)始终会在目标对象本身上生成属性。另一方面,属性的查找将参考原型链。
当您更改原型中存在的数组内容时:
a.array[0] = "foo";
你正在修改属性" array"通过对象" a"查找。该值可以在原型上找到,因此它是属性值赋值中使用的值。该声明在结构上是:
(someObject)[0] = "foo";
and here" someObject"是在原型上找到的那个数组。
但是,您可以直接在对象上设置属性:
a.str = "foo";
在这种情况下,JavaScript总是直接在目标对象上创建或更新属性,并且根本不会触及原型链。
答案 1 :(得分:2)
这不是一个错误。通过做
Class.prototype.array = [];
您创建了共享属性。但是通过做
instance.array = []
您创建的实例属性在实例之间既不共享也不可见。通过在构造函数中执行this.array = [];
,您只需覆盖共享引用。