Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prototype inheritance. obj->C->B->A, but obj.constructor is A. Why?

Tags:

javascript

var print = function(text){
  document.write(text);
  document.write("</br>");
}

var A = function(){
}
A.prototype.name="A";

var B = function(){
}
B.prototype = new A();
B.prototype.name="B";

var C = function(){
}
C.prototype = new B();
C.prototype.name="C";

obj = new C();
print(obj.name);
print(obj.constructor.prototype.name);
print(obj.constructor == A);

This code gives next output:

C
A
true

Why obj.constructor here is A and not C ?

like image 366
nahab Avatar asked May 13 '11 14:05

nahab


2 Answers

As seen in this code sample, you have to manually reset the .constructor property when using inheritance, or your constructor is being overridden when you call new A() or new B():

B.prototype = new A();
B.prototype.constructor = B; // need this line to fix constructor with inheritance

Here is a working sample: http://jsfiddle.net/93Msp/.

Hope this helps!

like image 111
mellamokb Avatar answered Sep 22 '22 19:09

mellamokb


To make a clear picture:

In the chain

 obj->"new B()"->"new A()"   // where obj is the same as "new C()"

only "new A()" object has property constructor. All the other objects get constructor property from the prototype chain.

In the code:

 var A = function(){
 }
 A.prototype.name="A";
 // A had not create "constructor" property for "new A()" 
 // so, looking at the prototype
 // According to ECMAScript spec 13.2.10
 // A.prototype.constructor == A
 // thus
 // "new A()".constructor == A

 var B = function(){
 }
 B.prototype = new A();
 B.prototype.name="B";
 // B had not create "constructor" property for "new B()" 
 // looking at the prototype
 // B.prototype is "new A()" 
 // as shown above 
 // "new A()".constructor == A
 // thus
 // B.prototype.constructor == A
 // and at the end
 // "new B()".constructor == A

 var C = function(){
 }
 C.prototype = new B();
 C.prototype.name="C";
 // C had not create "constructor" property for "new C()"/"obj" 
 // looking at the prototype
 // C.prototype is "new B()" 
 // looking up to "new B()".prototype
 // "new B()".prototype is "new A()" as shown above
 // "new A()".constructor == A
 // and finally
 // C.prototype.constructor == A

 obj = new C();
 print(obj.name);
 print(obj.constructor.prototype.name);
 print(obj.constructor == A);

So as wrote mellamokb we should overwrite(create, if more precise) constructor property.

like image 27
nahab Avatar answered Sep 21 '22 19:09

nahab