Reputation: 5155
Why when I instantiate a new object in JavaScript that has another object as one of its properties, does it always reference the same object?
For example
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
Also, what would be the appropriate way to make it create a new object property every time it is instantiated?
Upvotes: 0
Views: 82
Reputation: 26161
I would like to explain in the following code.
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
In the first code there is a closure and it is not shared. All instantiated objects have a separate closure. In the prototype version there is no closure and all instantiated objects access the very same object at the prototype of the constructor.
There is also a more complicated prototypical sharing of closures exist and that i had explained here in which we share the closure itself through the prototype.
Upvotes: 0
Reputation: 9470
In your code .status.num appear to belong to the class, not instance. Change your code to something like this:
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
Upvotes: 0
Reputation: 522110
Because that's what the prototype is: a shared object among all instances. You're explicitly creating the { num: 0 }
object only once, so it will exist only once. Javascript doesn't clone it for you when instantiating a new test
. Usually the prototype is used for functions, where this doesn't make any difference. If you want instance specific attributes, you need to create them in the constructor function:
function test() {
this.state = { num: 0 };
}
Upvotes: 2