实例化新对象引用相同属性

时间:2016-06-23 15:21:11

标签: javascript javascript-objects

为什么当我在JavaScript中实例化一个具有另一个对象作为其属性之一的新对象时,它是否总是引用同一个对象?

例如

function test() {}

test.prototype.state = {
    num: 0
};

var obj1 = new test();
var obj2 = new test();

obj1.state.num = 1;

console.log(obj1.state.num,obj2.state.num); // Outputs 1 1 instead of 1 0

此外,每次实例化时都会创建新对象属性的适当方法是什么?

3 个答案:

答案 0 :(得分:2)

因为原型是什么:所有实例中的共享对象。您只需显式创建一次{ num: 0 }对象,因此它只会存在一次。在实例化新的test时,Javascript不会为您克隆它。通常原型用于功能,这并没有任何区别。如果需要实例特定的属性,则需要在构造函数中创建它们:

function test() {
    this.state = { num: 0 };
}

答案 1 :(得分:0)

我想在下面的代码中解释。

function test() {
  var o = {a:1};
  this.geto = function(){return o.a};
  this.seto = function(v){o.a = v};
}

test.prototype.p = {a:0};

var obj1 = new test();
var obj2 = new test();

obj1.p.a = 100;
obj1.seto(50);
console.log(obj1.p.a);    // <- 100
console.log(obj2.p.a);    // <- 100
console.log(obj2.geto()); // <- 1
console.log(obj1.geto()); // <- 50

在第一个代码中有一个闭包,它不是共享的。所有实例化的对象都有一个单独的闭包。在原型版本中没有闭包,所有实例化的对象都在构造函数的原型中访问同一个对象。

还存在一个更复杂的原型共享闭包,我已经解释了here,其中我们通过原型共享闭包本身。

答案 2 :(得分:0)

在你的代码中.status.num似乎属于类,而不是实例。将您的代码更改为以下内容:

function test() {
  this.state = {num:0};//instance property
}
var obj1 = new test();
var obj2 = new test();

obj1.state.num = 1;

console.log(obj1.state.num,obj2.state.num);//1 0 as expected
相关问题