2

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/

html_programmer
  • 18,126
  • 18
  • 85
  • 158
  • 1
    Well, `child2` inherits the `.constructor` property from `Child.prototype`, so if you expect the one why don't you expect the other? – Bergi Jul 31 '15 at 10:51
  • Well, I would expect the constructor property to be `function Child()` because this would be the actual constructor of `child_2`. The inheritance only takes place via the prototype property of `Child`, which is overridden by the constructor Child itself. – html_programmer Jul 31 '15 at 10:56
  • The `.constructor` properties on the prototypes don't care what function was called to construct an instance. – Bergi Jul 31 '15 at 11:45
  • 1
    you can't set constructor read this http://pivotallabs.com/javascript-constructors-prototypes-and-the-new-keyword/ – maioman Jul 31 '15 at 11:53
  • @Bergi Thanks, that's what I figured out... I expected it to be always 1-1 correct (construct property / constructor function to construct the instance). It seems this wasn't the case anymore after messing around; made it a bit confusing though. – html_programmer Jul 31 '15 at 11:53

1 Answers1

1

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;
Community
  • 1
  • 1
Luke
  • 5,567
  • 4
  • 37
  • 66
  • Thanks for the elaborate answer. But how then can it be explained that when the prototype property of `Child` is replaced by the one of `Parent` (and thus also the constructor on the prototype), the constructor Child (where the name of the child is set) is still called in the first place? – html_programmer Jul 31 '15 at 11:17
  • `constructor` is specified as: 'Returns a reference to the Object function that created the instance's prototype.' It doesn't have to point to the function that created the instance itself. Here's the doc's for it: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor I highly suggest you read that SO answer i linked to in the question – Luke Jul 31 '15 at 11:23
  • My misunderstanding came from the assumption that the construct property was always meant to reflect that function that constructs the object (which for me seemed logical), but apparently it doesn't. Following the logic in your answer, I can see why the construct property returned function Parent. – html_programmer Jul 31 '15 at 11:59