2016-06-23 2 views
0

Почему при создании нового объекта в JavaScript, который имеет другой объект в качестве одного из его свойств, всегда ли он ссылается на один и тот же объект?Создание экземпляров нового объекта Свойство Same

Например

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 

Кроме того, что бы подходящий способ сделать это создать новый объект недвижимости каждый раз, когда он инстанцированный?

+0

Вот для чего предназначены прототипы. Если бы он не был в прототипе, а в самой конструкторской функции сам по себе как личная переменная, то вы каждый раз становились бы разными при создании объекта – Redu

ответ

2

Потому что это прототип: общий объект среди всех экземпляров. Вы явно создаете объект { num: 0 } только один раз, поэтому он будет существовать только один раз. Javascript не клонирует его для вас при создании нового test. Обычно прототип используется для функций, где это не имеет никакого значения. Если вы хотите экземпляра конкретных атрибутов, вам нужно создать их в функции конструктора:

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

Интересно, я не знал, что ... Есть ли другой способ достичь этого ? –

+0

По существу: нет. Конечно, есть много способов, которыми вы можете наклониться назад, чтобы сделать что-то более или менее похожее, но почему бы вам? Специфические атрибуты/значения экземпляра определяются в функции конструктора, присваивая 'this',« прототип »является общим для всех. Вот как это работает. – deceze

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, в котором мы совместно используем замыкание через прототип.

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 
Смежные вопросы