0

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

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

2 回答 2

2

字符串是不可变的,数组是可变的。您要替换字符串,但要修改数组。

如果您覆盖数组而不是修改它,您将在数组和字符串之间获得相同的行为。

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 : ''};
于 2012-05-08T17:32:56.353 回答
1

当你分配

c1.aString = 'a'

没有分配给aString原型中的字段。一个名为的新字段aString直接在c1对象中创建,并将该字段隐藏aString在原型中。

同时,当你打电话

c1.anArray.push('a');

in中没有anArray字段c1,因此您引用的是anArrayin 原型。你可以通过这样做来测试它

c1.anArray = new Array();

并注意在anArray中创建了一个新属性,而不是在原型中c1干扰。anArray在这种情况下,

console.log(c1.anArray);
console.log(c2.anArray);

会有不同的结果,c2仍然会引用anArrayin 原型。

如果直接在对象和原型中(甚至在原型链中)存在同名的字段,并且您请求该字段的值,则解释器首先直接查看对象,然后才向上查找原型链,直到它在某处找到该字段。

然而,如果你给一个字段赋值,它总是直接在对象中完成,而不是在它的原型中。

于 2012-05-08T17:29:03.140 回答