参考和原始原型值

时间:2012-05-08 17:25:23

标签: javascript javascript-objects

我不明白为什么数组在两个实例之间共享而原始类型不是。有人可以解释一下吗?

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);

2 个答案:

答案 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

如果在对象和原型中直接存在具有相同名称的字段(或者甚至在原型链中更远),并且您请求此字段的值,则解释器首先直接查看对象,然后上升原型链,直到它找到某个地方。

但是,如果为某个字段赋值,则它总是直接在对象中完成,而不是在原型中完成。