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?
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:
constructor
in child_2
? -- NO, follow the [[Prototype]]
Parent
class). Is constructor
here? -- No, follow the [[Prototype]]
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;