I have the following code (ObjA) and it works as I would expect, instance ‘a1’ has the same properties as ‘a2’ but with different values.
function ObjA() {
this.objLiteral = {};
this.propA = 0;
}
var a1 = new ObjA();
a1.objLiteral['hello'] = 3;
a1.propA = 1.5;
var a2 = new ObjA();
a2.objLiteral['goodbye'] = 4;
a2.propA = 2;
debugger info for a1 and a2:
http://www.flickr.com/photos/76617756@N02/6879283032/
Next, I have the following ObjB that inherits from ObjA. Instance ‘b1’ and ‘b2’ have the same properties and different values for properties propA and propB but for some reason, objLiteral is the same in both as if it was referencing the same object.
ObjB.prototype = new ObjA();
ObjB.prototype.constructor=ObjB;
function ObjB() {
this.propB = 2;
}
var b1 = new ObjB();
b1.objLiteral['hello2'] = 6;
b1.propA = 4;
b1.propB = 5;
var b2 = new ObjB();
b2.objLiteral['goodbye2'] = 8;
b2.propA = 6;
b2.propB = 7;
debugger info for b1 and b2:
http://www.flickr.com/photos/76617756@N02/6879283088/
Can somebody help me understand what is happening? What do I have to do to ge what I am expecting?
Your help is much appreciated.
Well, both objects
b1andb2have the same prototype, namely an instance ofObjA:hence they inherit and have access its properties.
b1.objLiteralandb2.objLiteralrefer to the same object:and
To fix that, you have to create a new object of each instance. This is normally done by calling the “parent” constructor inside the “child” constructor:
ObjA.call(this)will callObjAand within that function,thiswill refer to the argument passed tocall[MDN], in this case the new instance ofObjB:As you can see,
objLiteralis now property of each instance:To avoid this confusion in the first place, setting an instance of the parent constructor as the prototype of the child constructor should be avoided. What if the parent constructor expects instance specific arguments? What would you pass to
ObjAin this case?It’s better to set the prototype of the child constructor to the prototype of the parent constructor (with one level of indirection) and call the parent constructor like above:
Tmpto prevent extendingParent.prototypeif you extendChild.prototypelater on.Regarding
propA:It “works”, because you are assigning a new value to it.
Here are again the objects, after assigning properties to
x.objLiteralandx.propA. You can see that the objects don’t have an ownobjLiteralproperty, but an ownpropA:If instead you assign a new value to
objLiteral, e.g. throughb1will now have its own propertyobjLiteral, which shadows the inherited one: