Table of Contents
Most of the people who start learning about the core concepts of javascript get confused when they try to understand prototypes in javascript. This generally happens when they shift their focus from C++ or Java to Javascript. Inheritance is javascript works differently as compared to C++ or Java. In javascript, inheritance is more widely known as prototypal inheritance.
Things become very difficult to understand for a newbie when they encounter classes in javascript. The new class syntax looks very similar to the class syntax in C++ or Java but in reality, is very different.
In this article, we will generally try to understand prototypal inheritance in Javascript. We will also learn about the new class keyword in javascript and how it works in reality.
Understanding the need for Prototypes in Javascript
Most of the time while working with arrays, objects, and strings you would have noticed that they are many methods available by default.
For example:
var arr = [1,2,3,4];arr.reverse(); // returns [4,3,2,1]
var channel = "Technical Suneja";str.indexOf('T'); // returns 0
Have you ever wondered where these inbuilt methods come from? It is for sure that you haven’t defined these methods.
Can you create your own custom methods like this ?? Let us understand it with the help of an example
var numbers = [1,2,3,4];numbers.test = function() { return 'Welcome to TS Family';}arr.test(); // will return 'Welcome to TS Family'
The above example will work fine only for this variable called numbers. Let us consider another variable called number2 then number2.test() will throw an error “TypeError: number2.test is not a function”.
So you would have a question in your mind that how to make these methods available to each and every instance of array, string, and object. You might have another question in your mind it is possible to create your own methods with the same behavior. So the answer to this question is yes it possible but you have to do it in the right way. This can generally be done using prototypes in javascript.
Let us see how these functions are coming from
var number = [9,8,7,6]; var number2 = Array(9,8,7,6);
In the above example, we have generally created two arrays in two different ways. We have generally created the number array using array literal and number2 array with an Array constructor function.
Coming to the constructor function Array it is generally a predefined constructor function. If you check the Chrome Developer Tools and go to the console and type console.log(Array.prototype) and hit enter.
Here you will see all the methods that you are wondering about. So now you know about where these methods are coming from. Also, try this with String.prototype and Object.prototype.
Let us create a simple constructor function
var printName = function(name) { this.myName = name; this.tellMyName = function() { console.log(this.myName); }}
var printNameObj1 = new printName('Ajay Suneja'); printNameObj1.tellMyName(); //will print Ajay Suneja
The problem with the above code snippets is we are wasting memory with the above approach. Take a note that the method tellMyName is the same for each and every instance of printName. Every time when we create an instance of printName the method tellMyName ends up taking space in the sytems memory. If we use tellMyName as the same instance it is better to keep it at a single place and make all our instances from that place.
var printName = function(name) { this.myName = name;}
printName.prototype.tellMyName = function() { console.log(this.myName);}
var printNameObj1 = new printName('Ajay Suneja');printNameObj1.tellMyName(); //prints Ajay Suneja
I hope that by now you would have got a clear understanding of prototypes in javascript. Now we will understand the prototype in much more detail. Let us now understand about __proto in javascript. The __proto_ is generally a reference to the prototype object from where the instance has been inherited. Let us understand with the code below. As we already know that creating an array with array literals will inherit the properties from Array.prototype property.
var numbers = [4,3,2,1,8];
As I told you in the above statement that __proto_ is simply a reference to the object from where the instance has been inherited. So array.__proto should be the same as Array. prototype.
Let us verify it by running a simple code snippet in the browser.
According to the MDN docs __proto__ is highly discouraged and may not be supported by all browsers. So the correct way of doing it is given below:
var number = [4,5,2,1];var prototypeOfNumber = Object.getPrototypeOf(number);prototypeOfNumber === Array.prototype;prototypeOfNumber === arr.__proto__;
Prototype Chaining and Inheritance
In programming most of the time, we have to take something and extend it. In javascript, we can achieve inheritance with the help of prototype chaining. Let us consider a term called the vehicle. For instance, let us take an example of a user object with properties and methods and we want to make admin and guest a slightly modified variant of it.
Let us understand it with the help of an example
In the above example, we are able to access the property name of obj in obj2 by using __proto__. So the output to the console will be “Ajay Suneja”. This is also called prototypal inheritance in javascript.
Let us now extend the functionality by using a function getName inside obj.
Example :
Output
Now let us take another scenario when we have added the property “name” with the value to obj2.
Example
Output:
In the object obj2, there is a property name with the value “Vivek Suneja” so when we do console of obj2.getName() then the output to the screen will be Vivek Suneja instead of Ajay Suneja as the obj2 has name property attached to it already.