我不明白为什么数组在两个实例之间共享而原始类型不是。有人可以解释一下吗?
MyObject = function() {};
MyObject.prototype = {anArray : [],aString : ''};
var c1 = new MyObject();
c1.aString = 'a';
c1.anArray.push('a');
var c2 = new MyObject();
console.log(c2.aString);
console.log(c2.anArray);
答案 0 :(得分:2)
字符串是不可变的,数组是可变的。您正在替换String,但修改数组。
如果你覆盖数组而不是修改它,你会在数组和字符串之间得到相同的行为。
MyObject = function() {};
MyObject.prototype = {anArray : [],aString : ''};
var c1 = new MyObject();
c1.aString = 'a';
c1.anArray = []
c1.anArray.push('a');
var c2 = new MyObject();
console.log(c2.aString); // ''
console.log(c2.anArray); // []
因此,如果您计划允许所有实例观察对其的更改,那么仅在prototype
上放置对象或数组是有意义的。否则,只需将其直接放在实例上即可。
MyObject = function() {
this.anArray = [];
};
MyObject.prototype = {aString : ''};
答案 1 :(得分:1)
分配时
c1.aString = 'a'
你不分配原型中的aString
字段。名为aString
的新字段直接在c1
对象中创建,并隐藏原型中的aString
字段。
同时,当你打电话
c1.anArray.push('a');
anArray
中没有c1
字段,因此您在原型中引用了anArray
。您可以通过
c1.anArray = new Array();
并注意在anArray
中创建了一个新属性c1
,而不是干扰原型中的anArray
。在这种情况下,
console.log(c1.anArray);
console.log(c2.anArray);
会有不同的结果,因为c2
仍会引用原型中的anArray
。
如果在对象和原型中直接存在具有相同名称的字段(或者甚至在原型链中更远),并且您请求此字段的值,则解释器首先直接查看对象,然后上升原型链,直到它找到某个地方。
但是,如果为某个字段赋值,则它总是直接在对象中完成,而不是在原型中完成。