Reputation: 41
All the resources I have found, it says that if we use Javascript prototype pattern, that functions' prototype is shared between all the objects for that particular type. that means the following;
function TestObj(){
}
TestObj.prototype = {
cVar: 15,
increase: function(){
this.cVar++;
}
};
var a = new TestObj();
var b = new TestObj();
a.increase();
console.log(a.cVar); // 16
console.log(b.cVar); // 15 ??
Now my question is, shouldn't the b.cVar be 16? why is it 15 then? And if it is 15 that means the TestObj with protype is not shared between objects.
Do you know??
Upvotes: 3
Views: 476
Reputation: 19480
Yes, an object's prototype is shared between instances of the object, but the this.cVar++
looks a little bit misleading.
I think its easier to explain if you rewrite
this.cVar++;
as
this.cVar = this.cVar + 1;
The important thing is that this
refers to the object instance and not the prototype. So in this.cVar + 1
it'll check the object instance to see if it has a cVar
property. The first time increase
is called, it doesn't. So JavaScript will look up the prototype chain until it finds it. So it finds 15
. However, when it does the actual assignment back to this.cVar
, it sets the property on the object instance itself and not the prototype (a shadowing of sorts).
So in your example,
console.log(a.cVar); // returns property from `a` itself
console.log(b.cVar); // returns property from the prototype
We can show this by using hasOwnProperty
:
console.log( a.hasOwnProperty( "cVar" ) ); // true
console.log( b.hasOwnProperty( "cVar" ) ); // false
Upvotes: 6
Reputation: 13672
Objects do, in fact, share the prototype with one another as your research has lead you to believe. However, as go-oleg
eluded to, there is a concept of the prototype chain. The prototype chain has a couple of behaviors you have to understand.
When you try to access a property on an object, it recursively looks up the chain starting from the object and looks for the property, then returns the value (This is what happens in the case of a read/get action).
When you try to set the value on a property on an object, it doesn't bother to recurse up the chain to find the property in the chain. Instead, if it doesn't find one on the object, it just adds the property along with the value you set on the object itself. This effectively hides the property that is higher up the prototype chain (This is what happens in the case of a write/set action).
If you placed your value inside an object then tried to set the value however, it would recurse to the object reference in a read attempt and since you have a reference pointer to the object, you would be setting the value on the object directly which would have the outcome you were expecting:
function TestObj(){
}
TestObj.prototype = {
cVar: 15,
obj: { val: 5 },
increase: function(){
this.cVar++;
},
objInc: function() {
this.obj.val++;
}
};
var a = new TestObj();
var b = new TestObj();
a.increase();
console.log(a.cVar);
console.log(b.cVar);
b.objInc();
console.log(a.obj.val);
console.log(b.obj.val);
//output
//16
//15
//6
//6
Hopefully that distinction clears up the confusion.
Upvotes: 3
Reputation: 4223
Your getting confused by the terminology, and TestObject
a
is the only TestObject
that you call increase()
on. So it makes sense that a = 16
and b = 16
, since you never call b.increase()
.
... that functions' prototype is shared between all the objects for that particular type.
That doesn't mean that each time any TestObject
calls increase()
then every other TestObject
and itself also increase their cVar
. Your thinking of something similar to the way that an EventListener
and EventDispatcher
system is set up. That function's prototype shared between all the objects for that particular type means that each TestObject
instance has the prototype you defined.
Upvotes: 0
Reputation: 576
To be clear, "a" is an object, "b" is another, separate, object. You then call the increase function only on "a", not "b". Therefore, unless I'm off my rocker, It would make sense that b.cVar = 15, since it was never incremented.
Upvotes: 0