1

I was looking for good example of Javascript prototypical inheritance on SO and this question, Benefits of using 'Object.create' for inheritance, has an excellent answer and so I tried to push my luck by adding another object type to the prototype chain and I found something that looks strange.

The original listing has Dog inheriting from Animal and we can see Animal in the prototype chain. However, if we add Creature and have Animal inheriting from that then Animal disappears from the reported prototype chain if we use console.info.

Can anyone explain why the prototype chain shouldn't say Dog->Animal->Creature ?

enter image description here

Here is code listing

"use strict";

//https://www.typescriptlang.org/docs/handbook/classes.html
var Creature = (function () {
    function Creature() {
        return this;
    }

    Creature.prototype.deadOrAlive = function () {
        console.log("alive"); //hard code for now
    }

    return Creature;
}());

var Animal = (function () {

    Animal.prototype = Object.create(Creature.prototype);

    function Animal() {
        return this;
    }

    Animal.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) {
            distanceInMeters = 0;
        }
        console.log("Animal moved " + distanceInMeters + "m.");
    };

    return Animal;
}());

var Dog = (function () {

    /* https://stackoverflow.com/questions/17392857/benefits-of-using-object-create-for-inheritance/17393153#answer-17393153 */
    Dog.prototype = Object.create(Animal.prototype);

    function Dog() {
        return this;
    }
    Dog.prototype.bark = function () {
        console.log("Woof! Woof!");
    };
    return Dog;
}());

var dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();
dog.deadOrAlive();
//debugger; 
S Meaden
  • 8,050
  • 3
  • 34
  • 65
  • "*Can anyone explain why the prototype chain shouldn't say `Dog`->`Animal`->`Creature`?*" - the prototype chain is `dog`->`Dog.prototype`->`Animal.prototype`->`Creature.prototype`->`Object.prototype`->`null`. What the debugger shows you are just derived labels on these objects, and not always helpful. – Bergi Jun 06 '21 at 21:35

1 Answers1

0

A colleague at a Javascript boot camp of which I am member has come up with a one-line solution, just use Object.setPrototypeOf( Animal.prototype, Creature.prototype ). Thanks, Ray!

//https://www.typescriptlang.org/docs/handbook/classes.html
"use strict";

var Creature = (function () {
    function Creature() {
        return this;
    }

    Creature.prototype.deadOrAlive = function () {
        console.log("alive"); //hard code for now
    }

    return Creature;
}());

var Animal = (function () {
    Object.setPrototypeOf( Animal.prototype, Creature.prototype )

    function Animal() {
        return this;
    }

    Animal.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) {
            distanceInMeters = 0;
        }
        console.log("Animal moved " + distanceInMeters + "m.");
    };

    return Animal;
}());

var Dog = (function () {
    /* https://stackoverflow.com/questions/17392857/benefits-of-using-object-create-for-inheritance/17393153#answer-17393153 */
    Object.setPrototypeOf( Dog.prototype, Animal.prototype )

    function Dog() {
        return this;
    }
    Dog.prototype.bark = function () {
        console.log("Woof! Woof!");
    };
    return Dog;
}());

var dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();
dog.deadOrAlive();
//debugger;

enter image description here

S Meaden
  • 8,050
  • 3
  • 34
  • 65
  • 1
    If you're using ES6 `Object.setPrototypeOf`, you may as well just use an ES6 `class` declaration :-) The use of `Object.create` is still recommended for ES5 code, and very educational. – Bergi Jun 06 '21 at 21:32