Good Example of JavaScript's Prototype-Based Inheritance Good Example of JavaScript's Prototype-Based Inheritance javascript javascript

Good Example of JavaScript's Prototype-Based Inheritance


As mentioned, the movies by Douglas Crockford give a good explanation about the why and it covers the how. But to put it in a couple of lines of JavaScript:

// Declaring our Animal objectvar Animal = function () {    this.name = 'unknown';    this.getName = function () {        return this.name;    }    return this;};// Declaring our Dog objectvar Dog = function () {    // A private variable here            var private = 42;    // overriding the name    this.name = "Bello";    // Implementing ".bark()"    this.bark = function () {        return 'MEOW';    }      return this;};// Dog extends animalDog.prototype = new Animal();// -- Done declaring --// Creating an instance of Dog.var dog = new Dog();// Proving our caseconsole.log(    "Is dog an instance of Dog? ", dog instanceof Dog, "\n",    "Is dog an instance of Animal? ", dog instanceof Animal, "\n",    dog.bark() +"\n", // Should be: "MEOW"    dog.getName() +"\n", // Should be: "Bello"    dog.private +"\n" // Should be: 'undefined');

The problem with this approach however, is that it will re-create the object every time you create one. Another approach is to declare your objects on the prototype stack, like so:

// Defining test one, prototypalvar testOne = function () {};testOne.prototype = (function () {    var me = {}, privateVariable = 42;    me.someMethod = function () {        return privateVariable;    };    me.publicVariable = "foo bar";    me.anotherMethod = function () {        return this.publicVariable;    };    return me;}());// Defining test two, functionvar testTwo = ​function() {    var me = {}, privateVariable = 42;    me.someMethod = function () {        return privateVariable;    };    me.publicVariable = "foo bar";    me.anotherMethod = function () {        return this.publicVariable;    };    return me;};// Proving that both techniques are functionally identicalvar resultTestOne = new testOne(),    resultTestTwo = new testTwo();console.log(    resultTestOne.someMethod(), // Should print 42    resultTestOne.publicVariable // Should print "foo bar");console.log(    resultTestTwo.someMethod(), // Should print 42    resultTestTwo.publicVariable // Should print "foo bar");// Performance benchmark startvar stop, start, loopCount = 1000000;// Running testOnestart = (new Date()).getTime(); for (var i = loopCount; i>0; i--) {    new testOne();}stop = (new Date()).getTime();console.log('Test one took: '+ Math.round(((stop/1000) - (start/1000))*1000) +' milliseconds');// Running testTwostart = (new Date()).getTime(); for (var i = loopCount; i>0; i--) {    new testTwo();}stop = (new Date()).getTime();console.log('Test two took: '+ Math.round(((stop/1000) - (start/1000))*1000) +' milliseconds');

There is a slight downside when it comes to introspection. Dumping testOne, will result in less useful information. Also the private property "privateVariable" in "testOne" is shared in all instances, als helpfully mentioned in the replies by shesek.


Douglas Crockford has a nice page on JavaScript Prototypal Inheritance:

Five years ago I wrote Classical Inheritance in JavaScript. It showed that JavaScript is a class-free, prototypal language, and that it has sufficient expressive power to simulate a classical system. My programming style has evolved since then, as any good programmer's should. I have learned to fully embrace prototypalism, and have liberated myself from the confines of the classical model.

Dean Edward's Base.js, Mootools's Class or John Resig's Simple Inheritance works are ways to do classical inheritance in JavaScript.


function Shape(x, y) {    this.x = x;    this.y = y;}// 1. Explicitly call base (Shape) constructor from subclass (Circle) constructor passing this as the explicit receiverfunction Circle(x, y, r) {    Shape.call(this, x, y);    this.r = r;}// 2. Use Object.create to construct the subclass prototype object to avoid calling the base constructorCircle.prototype = Object.create(Shape.prototype);