1

If I assign a parent to my subtype's prototype inside my function, my subtype's prototype ends up pointing to Subtype instead of SuperType. Why is this?

function SubType( name ){
}               
SubType.prototype = new SuperType(); 

 // THE ABOVE WORKS :)

 function SubType(){
        SubType.prototype = new SuperType(); 
 }   

// THE ABOVE DOESN'T WORK :(
Adam Dreaver
  • 341
  • 1
  • 7
  • A bit off topic but if you want to inherit without calling the super constructor you can use `SubType.prototype=Object.create(SuperType)` this will set the SubType.prototype.constructor wrongly so you have to repair that if you use it or use a helper function to inherit: http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711 – HMR Jul 13 '13 at 02:21

3 Answers3

2

It's because of the way the new operator works in JavaScript. When you use new before a function call this is what happens:

  1. We create a new object from the prototype of the function (e.g. var instance = Object.create(func.prototype)).
  2. We set the this pointer of the function to the newly created object (e.g. var result = func.apply(instance, arguments)).
  3. If the result is not an object or a function we return the instance (e.g. if (typeof result === "object" || typeof result === "function") return result; else return instance;).

Now forget everything else and only concentrate on the first point - the instance object creation phase.

Example 1:

function SubType(name) {
}

SubType.prototype = new SuperType;

// THE ABOVE WORKS :)

Here we're setting the prototype of SubType to new SuperType outside the constructor. Hence when you call new SubType JavaScript creates a new object which inherits from SubType.prototype which is new SuperType at that time. Hence the instance inherits from SuperType as well.

Example 2:

function SubType() {
    SubType.prototype = new SuperType;
}

// THE ABOVE DOESN'T WORK :(

Here we're calling new SubType before we set SubType.prototype to new SuperType. Hence the instance object inherits from SubType.prototype before it was set to new SuperType. Hence the instance doesn't inherit from SuperType.

Conclusion:

To understand how inheritance works in JavaScript I recommend you read the following articles:

  1. JavaScript inheritance and the constructor property - Stack Overflow
  2. No ways to have class-based objects in javascript? - Stack Overflow
  3. javascript - Benefits of prototypal inheritance over classical? - Stack Overflow
  4. Aadit M Shah | Why Prototypal Inheritance Matters
Community
  • 1
  • 1
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
1

Having it inside the constructor resets the prototype with each new instance created, but also requires that you create at least 1 instance for it to inherit.

function SubType(){
    SubType.prototype = new SuperType(); 
}

var before = SubType.prototype;
new SubType();

console.log(before === SubType.prototype);  // false

var current = SubType.prototype;
new SubType();

console.log(before === SubType.prototype);  // false
console.log(current === SubType.prototype); // false
console.log(before === current);            // false

Inheritance should typically be established before any instances are created, which requires the prototype chain be set outside the constructor:

function SubType() {}
SubType.prototype = new SuperType();

var before = SubType.prototype;

new SubType();

console.log(before === SubType.prototype); // true
Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199
-1

Because you only have defined SubType in the second case, you haven't executed the function SubType.

function SubType( name ){
}               
SubType.prototype = new SuperType(); 

 // THE ABOVE WORKS :)

 function SubType(){
        SubType.prototype = new SuperType(); 
 }   

 SubType();

// THE ABOVE WILL WORK NOW
mohkhan
  • 11,925
  • 2
  • 24
  • 27