原型中的对象属性

时间:2013-12-10 10:00:08

标签: javascript

我有一个问题我无法解决,因为我无法解释这种行为:

var A = function(value) {
    this.prop = value;
};

A.prototype = {
    prop: 0
};

var a = new A(1);
var b = new A(2);

console.log(a.prop);
console.log(b.prop);

输出:

1
2

但是,使用此代码(几乎相同):

var A = function(value) {
    this.prop.value = value;
};

A.prototype = {
    prop: {
        value: 0
    }
};

var a = new A(1);
var b = new A(2);

console.log(a.prop.value);
console.log(b.prop.value);

我有这个输出:

2
2

有人能解释一下吗? 感谢...

编辑:

这是一个解决方案:

var A = function(value) {
    this.prop = {};
    this.prop.value = value;
};

A.prototype = {

};

var a = new A(1);
var b = new A(2);

console.log(a.prop.value);
console.log(b.prop.value);

4 个答案:

答案 0 :(得分:1)

原型只创建一次,它只是一个简单的对象,其子项附加于它所属的函数的所有实例。

所以它与你写的基本相同:

var obj = { value: 0 };

var a = {}, b = {};

a.obj = obj;
b.obj = obj;

obj.value = 2;

正如您所看到a.objb.obj对同一obj的引用,a.obj.valueb.obj.value都是2示例

答案 1 :(得分:1)

将原型属性视为在所有实例之间共享的属性 但是你可以在每个实例上覆盖它,这就是你在第一个例子中所做的 一旦在每个实例中重写,您就不再使用obj.prop访问prototype属性,而obj.prop现在引用了instance属性。您需要使用obj.prototype.prop再次读取它,但此语法是非法的:您可以使用obj.__proto__.prop(非标准)或Object.getPrototypeOf(obj).prop(EcmaScript 5)来执行此操作。
在第二个实例中,您不会更改构造函数中的属性:而是更改此属性的属性。所以两个构造函数都访问同一个对象,然后更改其中一个属性值,所以最后设置它将“赢”。这里,prototype属性不被instance属性覆盖('hidden'),并且访问obj.prop实际上访问'obj.prototype.prop'。

答案 2 :(得分:1)

这种情况正在发生,因为在JS中,对象是通过引用传递的,而原语则不是。

由于原型在两个实例之间共享,因此修改其上的对象将更新所有实例。

答案 3 :(得分:1)

在示例1中,this.prop基元类型,它由值引用,因此不在实例之间共享。

在示例2中,this.prop Object ,其引用是从单个对象的原型初始化的,因此所有实例共享此单个对象

在上一个“示例”解决方案中,您使用= {}创建一个新对象,因此所有实例现在都有自己的对象。

有关原始类型的更多详细信息:Primitive value vs Reference value

相关问题