5. Prototype based inheritance in JavaScript
As we have seen in our last post the association of prototype and __proto__ objects creates the interesting phenomenon of prototype based inheritance in JavaScript. EcmaScript has specified some rules for controlling the behavior of [[prototype]] object.They are:
All objects have an internal property called
[[prototype]]whose value is eithernullor an object and it will be used for implementing inheritance.Every prototype chain must have a finite length, i.e. if we recursively start accessing the
[[prototype]]object of an object, this internal property must eventually terminate atnull.
So how does the inheritance look like? Let's visualize it: For this let us take the stages of human evolution as our inheritance chain:
Australopithecus afarensis->Homo habilis->Homo erectus->Homo neanderthalensis->Homo sapiens
The inheritance would look something like this:

So here:
All constructor function’s
__proto__property points to theprototypeproperty of the JavaScriptFunctionconstructor functionAll constructor function’s
prototypeproperty points to an objectThe
constructorproperty of theprototypeobject of a constructor function points to the constructor function itselfThe
__proto__property of theprototypeobject of a constructor function points either to it’s parent constructor function’sprototypeproperty or toprototypeproperty of the JavaScriptObjectconstructor function. And this is the mechanism used in JavaScript to inherit methods of its parent objects. Ultimately the__proto__property of theObjectconstructor function points tonull
So why is this mechanism so powerful? Let's see some code We define a constructor function and create 2 object using it
function MyPseudoClass(welcomeString){
this.welcomeString = welcomeString;
}
var myPseudoClassObject1 = new MyPseudoClass("My precious");
var myPseudoClassObject2 = new MyPseudoClass("gollum gollum!");
console.log(myPseudoClassObject1);//Output MyPseudoClass { welcomeString: 'My precious' }
console.log(myPseudoClassObject2);//Output MyPseudoClass { welcomeString: 'gollum gollum!' }
So each of the objects created contains it's own copy of the property welcomeString. Let us assume we want the objects of MyPseudoClass to have the ability to print the welcomeString property. One way of doing it is adding a method to MyPseudoClass. Let's see how the objects would look then.
function MyPseudoClass(welcomeString){
this.welcomeString = welcomeString;
this.printWelcomeString = function(){
console.log(this.welcomeString);
};
}
var myPseudoClassObject1 = new MyPseudoClass("My precious");
var myPseudoClassObject2 = new MyPseudoClass("gollum gollum!");
myPseudoClassObject1.printWelcomeString();// Output My precious
myPseudoClassObject2.printWelcomeString();//Output gollum gollum!
console.log(myPseudoClassObject1);//Output MyPseudoClass { welcomeString: 'My precious', printWelcomeString: [Function] }
console.log(myPseudoClassObject2);//Output MyPseudoClass { welcomeString: 'gollum gollum!', printWelcomeString: [Function] }
So each object has its own copy of printWelcomeString method. In real life scenarios this will cause repetition of the method in all the object instances even though it's definition is the same for all the objects unlike the welcomeString property which varies for each object. So this will lead to high memory consumption. Also any object inheriting from(i.e. pointing to the prototype property of the MyPseudoClass constructor function will not have access to the printWelcomeString method. How to avoid this? Simply move the printWelcomeString property from the constructor function to it's prototype object. Now we see the objects created don't have the method in them but still can access it as it's available to them in their prototype chain(i.e. myPseudoClassObject1.__proto__.printWelcomeString())
function MyPseudoClass(welcomeString){
this.welcomeString = welcomeString;
}
var myPseudoClassObject1 = new MyPseudoClass("My precious");
var myPseudoClassObject2 = new MyPseudoClass("gollum gollum!");
MyPseudoClass.prototype.printWelcomeString = function(){
console.log(this.welcomeString);
};
myPseudoClassObject1.printWelcomeString();// Output My precious
myPseudoClassObject2.printWelcomeString();//Output gollum gollum!
console.log(myPseudoClassObject1);//Output MyPseudoClass { welcomeString: 'My precious'}
console.log(myPseudoClassObject2);//Output MyPseudoClass { welcomeString: 'gollum gollum!' }
console.log(MyPseudoClass.prototype)//Output MyPseudoClass { printWelcomeString: [Function] }
Now let's create a child class and make it inherit the MyPseudoClass.
function MyPseudoClass(welcomeString){
this.welcomeString = welcomeString;
}
console.log(MyPseudoClass.prototype); //Output MyPseudoClass {}
function MyPseudoChildClass(hobbitName){
this.hobbitName = hobbitName;
}
MyPseudoChildClass.prototype.__proto__ = MyPseudoClass.prototype;
console.log(MyPseudoChildClass.prototype); //Output MyPseudoChildClass {}
console.log(MyPseudoChildClass.prototype.__proto__); //Output MyPseudoClass { printWelcomeString: [Function] }
var myPseudoChildClassObject = new MyPseudoChildClass("Frodo");
console.log(myPseudoChildClassObject) //Output MyPseudoChildClass { hobbitName: 'Frodo' }
console.log(myPseudoChildClassObject.__proto__) //Output MyPseudoChildClass {}
console.log(myPseudoChildClassObject.__proto__.__proto__)// Output MyPseudoClass { printWelcomeString: [Function] }
console.log(myPseudoChildClassObject.__proto__.__proto__.__proto__) // Output {}
console.log(myPseudoChildClassObject.__proto__.__proto__.__proto__.__proto__) //Output null
So, this proves what we just understood about the JavaScript prototype chain:
MyPseudoChildClass.prototype.__proto__ = MyPseudoClass.prototype;This is where the actual inheritance happens and a link is added the existing prototype chain of Object->MyPseudoClass.
myPseudoChildClassObject.__proto__points to theprototypeproperty ofMyPseudoChildClass.myPseudoChildClassObject.__proto__ === MyPseudoChildClass.prototypeis truemyPseudoChildClassObject.__proto__.__proto__points toportotypeproperty ofMyPseudoClass. myPseudoChildClassObject.proto.proto === MyPseudoClass.prototype` is true.myPseudoChildClassObject.__proto__.__proto__.__proto__points to theprototypeproperty ofObjectconstructor function.myPseudoChildClassObject.__proto__.__proto__.__proto__ === Object.prototypeis truemyPseudoChildClassObject.__proto__.__proto__.__proto__ === Object.prototypepoints to the__proto__property of prototype of theObjectconstructor function which is alwaysnull.myPseudoChildClassObject.__proto__.__proto__.__proto__.__proto__===Object.prototype.__proto__is true.
So this sums up the basics of how prototype based inheritance is achieved in JavaScript.
In the next post we will learn about accessing the prototype chain, the remaining method of object creation Object.create and then compare the important difference between the various methods of object creation.
References
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#Using_prototypes_in_JavaScript https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
About the author
I am a software developer by profession. I have been growing in the world of Software development for quite some time now and have navigated my way through various technologies, stacks, development methodologies, frameworks, patterns and each of them were unique experiences. Its exciting to be part of this evolution that is not only catering to solving day-to-day problems but is creating scope for the scientific world to develop by solving its "logico-mathemetical" problems. Cheers!
Comments
Join the discussionNo comments yet. Be the first to comment.
The JavaScript Experience
In this series, I will explore the features of ES5 & ES6 which is the specification on which JavaScript is based and try to understand them in simple terms.

