Search code examples
javascriptprototypal-inheritance

Prototypical inheritance: constructor of child


I was playing around with prototypical inheritance, and bumped into something I found a bit remarkable. Here is the case:

function Parent(){ 
    this.name = "parent"; 
    this.age = 30; 
}; 

var parent = new Parent();  
console.log(parent.constructor); //Prints function Parent();

function Child(){
    this.name = "child"; 
    this.age = 10; 
}; 

var child = new Child(); 
console.log(child.constructor); //prints function Child() 

Child.prototype = new Parent(); //Set inheritance 
console.log(Child.prototype.constructor); //prints function Parent() as expected 

var child_2 = new Child(); 
console.log(child_2.constructor); //prints function Parent() ?? 

console.log(child_2.name); //Yet prints child, meaning the child's constructor is still function Child() 

Although I am not surprised that the constructor of Child is function Parent() after the inheritance is defined, I am a bit surprised that the constructor of child_2 is function Parent(), because the property set in the constructor body of Child, ie.

this.name = "child"  

Is still executed.

Is there a practical reason behind this occurrence?

http://jsfiddle.net/7yobzt0u/1/


Solution

  • The Docs touch on this a little bit, but mostly just reference this SO question for the answer.

    As you have seen, constructor is a property on a function's prototype not the object itself. The only reason myObj.constructor returns something is because myObj's [[Prototype]] points to its constructor function's prototype property.

    When you said: child.prototype = new Parent() you made Child.prototype point to an "instance" of the parent "class".

    Then, when you said child_2 = new Child() that instance is what got copied to child_2's [[Prototype]]

    So when you said console.log(child_2.constructor) the lookup chain was as follows:

    1. Is constructor in child_2? -- NO, follow the [[Prototype]]
    2. We landed in this object, (which is an "instance" of the Parent class). Is constructor here? -- No, follow the [[Prototype]]
    3. We are now in the Parent.prototype object, is constructor here? --- Yes! return it.

    Rather than using new I suggest setting child's prototype with Object.create() but I suppose that's neither here nore there in regards to this question. Regardless, you need to set the constructor property manually, as referenced in the docs.

    Child.prototype = Object.create(Parent.prototype); 
    Child.prototype.constructor = Child;