Grasping prototypical Inheritance through pseudoclassical instantiation (JavaScript)

When using constructor functions for inheritance in JavaScript, you:

  1. Make the prototype property of the “derived” constructor an object whose prototype is the prototype property of the “base” constructor.

  2. Set the constructor property on the “derived” constructor’s prototype property to point to the “derived” constructor.

  3. Call the “base” constructor from the “derived” constructor with the correct this.

Like this:

var Infant = function() {
    this.age  = 0;
    this.color="pink";
    this.food = 'milk';
};
Infant.prototype.eat = function(){
    return /*...something...*/; // Returning `this.eat` doesn't make any sense, that's the function we're in
};

var Adolescent = function() {

    // #3 Give super a chance to initialize the instance, you can pass args if appropriate
    Infant.call(this);

    this.age = 5;
    this.height="short";
    this.job = 'keep on growing';
};

// Set up Adolescent's prototype, which uses Infant's prototype property as its prototype
Adolescent.prototype = Object.create(Infant.prototype);     // #1
Object.defineProperty(Adolescent.prototype, "constructor",  // #2
    value: Adolescent,
    writable: true,
    configurable: true
});
// (In pre-ES5 environments that don't event have `Object.defineProperty`, you'd use
// an assignment instead: `Adolescent.prototype.constructor = Adolescent;`

Object.create was added in ES5, so it won’t be present on obsolete JavaScript engines like the one in IE8. The single-argument version of it used above can be easily shimmed, though.

In ES2015 we have the option of doing it with the new class semantics:

class Infant {
    constructor() {
        this.age  = 0;
        this.color="pink";
        this.food = 'milk';
    }

    eat() {
        return /*...something...*/;
    }
}

class Adolescent extends Infant {            // extends does #1 and #2
    constructor() {
        super();                             // #3, you can pass args here if appropriate

        this.age = 5;
        this.height="short";
        this.job = 'keep on growing';
    }
}

Leave a Comment