The javascript prototypes are one of the most important concepts of Javascript since it is the mechanism by which Javascript objects inherit features from one another.
Additionally, inheritance is a common concept in the most modern programming languages, and many times people, even more, experienced programmers, are having difficult times understanding and using it in certain situations.
As I mentioned before, the javascript prototypes are the foundation stone on how the Javascript implements the inheritance between objects, therefore it can be proved a difficult concept to familiarize with.
In this article, you are going to learn what a prototype is, the logic behind the prototype chaining, what is the property shadowing technique, and how the Javascript engine implements object inheritance.
Requirements
In order to understand better these concepts, you have to be familiar with the following concepts
- Javascript objects
- Javascript object constructor
- this keyword
For reasons of completeness of this article, I will give a short definition of each of these terms.
Javascript Objects
You can consider JavaScript objects as containers for named values called properties. Objects can also have methods that are basically properties with functions as values.
Javascript constructor
The main purpose of a constructor is to create and initialize an object instance. You can call a constructor using the new keyword.
‘this’ keyword in Javascript
The JavaScript this keyword refers to the object it belongs to.
What is a Javascript prototype object?
As you may know, Javascript is a dynamic prototype-based object-orientation language.
A prototype is a hidden built-in property that you can find in every Javascript object by default.
Furthermore, a prototype is a special type of enumerable object itself, so each prototype has its own prototype, making a prototype chain. The chain ends when the last prototype object has null for its own prototype.
Additionally, you can use a prototype as a basis to create other objects.
Each object that you create from the same prototype, will share a similar structure meaning that will contain the properties and methods of its prototype.
In order to have a better understanding of this let’s see some examples.
See the Pen
attach properties to object by codebitshub (@codebitshub)
on CodePen.
In the example above, I create two objects named south_china_tiger and indo_chinese_tiger from the same function constructor. So they share a similar structure.
As you can see the following properties numOfLegs, eats, breed are defined in both objects.
Apart from that, in each object, I can define its own properties/methods. So in this case you can see that the property age is defined only for the indo_chinese_tiger.
What if I want to share new properties?
In order to add new properties that will be shared across all the created objects, I can use the prototype property and add them there.
See the Pen
prototype construction and shared properties by codebitshub (@codebitshub)
on CodePen.
In the above example, you can see that the property age is added to the prototype and is shared across the south_china_tiger and indo_chinese_tiger objects.
As you can see in the above example, the Animal’s prototype property can be accessed using <function-name>.prototype.
On the other hand, an object (instance) does not expose its prototype property. Instead, you can access it using the <object-name>.__proto__ property or with the method Object.getPrototypeOf().
Additionally, you can see that each prototype object has the following properties by default.
Furthermore, as MDN mentions the standard way to access an object’s prototype, since ECMAScript 5 and is available since IE 9, is the Object.getPrototypeOf() method.
Replace Javascript prototypes
Let’s see an example of replacing a prototype object.
See the Pen
Replacing Prototype Object by codebitshub (@codebitshub)
on CodePen.
In the code above, I first create two objects from the same constructor function and prototype. Next, I am replacing the prototype object with a new object.
As I already mentioned, each object’s prototype is linked to the function’s prototype object.
So what is going to happen if you replace the function’s prototype object, is that only the new objects are going to be linked to the changed prototype object because the new prototype object will reference a brand new address in memory.
On the other hand, the objects that were created before the prototype replacement will still link to the previous prototype of function which is the previous memory address.
Update Javascript prototypes
Let’s try this time to update a prototype instead of a replacement.
See the Pen
Updating prototype properties by codebitshub (@codebitshub)
on CodePen.
As you can see in the code above, if you update the prototype properties then older and new objects will share the same updated property.
This happens because the prototype object is a single object stored that references a very specific address in memory and is linked to every object created with the same constructor function.
Note: It is not advisable to modify the prototypes of standard JavaScript objects. You should modify only your own prototypes.
Javascript Prototypes Chaining
As it is already mentioned, when a new object is created then it inherits all the properties and methods from its prototype. The prototype itself is an object, so it inherits all the properties and methods from its own prototype.
So when a property of an object is accessed the Javascript engine, will search in the properties of the object to find it.
If the property does not exist, then it goes up in the hierarchy and checks the prototype object of the Object function, because all the objects are derived from the Object function in JavaScript.
The same process will take place for each prototype object until the property is found or the object will be equal to null which means the end of the prototype chain.
You can see how the Javascript engine walks through the prototype chain in the following example
See the Pen
Prototype chain by codebitshub (@codebitshub)
on CodePen.
The above code will print in the logs the following
Animal.prototype {}
Object.prototype {}
null
As you can see in the code above, I first define a function constructor named Animal and then an object named south_china_tiger from it.
In order to walk through the prototype chain, I am using a do-while loop. The loop will continue to execute until the prototype object will equal to null.
Shadowing Javascript prototypes
Let’s see what will happen if you define a property in an object that is predefined in the object’s prototype.
See the Pen
Shadowing properties by codebitshub (@codebitshub)
on CodePen.
Since I already explained the concept of the prototype chain I can use it to explain what is happening in the above code.
When the Javascript engine accesses the property eats of the object south_china_tiger it will first look in the object south_china_tiger.
It will find that it is defined there and will stop walking the prototype chain immediately.
The Javascript engine would access the eats property in the prototype only if it wasn’t defined as a property in the south_china_tiger object.
This technique is called shadowing the property.
Inheritance
Usually, you can use the prototype objects to find properties and methods of an object and/or to implement inheritance in JavaScript.
In this section, you can see how you can implement prototypical inheritance in Javascript.
There are various ways so let’s see them by example.
Object literal method
The first method is using object literal.
See the Pen
Inheritance – Object literal by codebitshub (@codebitshub)
on CodePen.
In the above code, I am using the method Object.setPrototypeOf to set the prototype of my_dog object to the dog’s object.
As you can see, the object my_dogs inherits all the properties and methods from the dogs object while in parallel is preserving its own properties and methods.
In the logs, you can also see that the constructor of the my_dogs object is the Object constructor.
As an alternative to the Object.setPrototypeOf method, I could use the following line of code to set the prototype of the my_dogs object
my_dogs.__proto__ = dogs;
I would not encourage this approach though as I mentioned earlier.
Object.create method
As an alternative I can use the Object.create method too.
See the Pen
Inheritance – Object.create by codebitshub (@codebitshub)
on CodePen.
In the above, code you can see again, that the my_dogs object inherits all the properties and methods of the dogs object.
If you open the console logs you can see that the prototype of the my_dogs object is still the Object constructor.
Constructor method
Another method to implement the prototypal inheritance in Javascript is the constructor method.
See the Pen
Inheritance – constructor method by codebitshub (@codebitshub)
on CodePen.
In the code above, I create an Animal constructor function with properties num_of_legs, eats, breed, sound. Next, I add the getDetails function to its prototype.
Now I want to create an object with the name Dog that will inherit all of the properties and methods of Animal.
In order to do that, I will use the Dog constructor function that will pass all of its arguments to the Animal constructor function with the help of Animal.call method.
As you can see in the logs, the constructor of the Dog object is the Animal object.
Finally, the Dog object will inherit the getDetails method of its prototype despite the fact that I did not define it in its own properties and methods.
ES6 class method
Javascript Classes are introduced in ECMAScript 2015 version (ES6) and are templates for Javascript Objects.
You can consider Javascript Classes as just syntactical sugar on top of prototypical inheritance that derives new classes from other classes.
See the Pen
Inheritance – ES6 class by codebitshub (@codebitshub)
on CodePen.
As you can see in the code above, I have two classes where the class My_Dogs extends the class Dogs.
Each class has a constructor function. The class My_Dogs calls the constructor function of the Dogs class and passes all the required arguments to the Dogs constructor.
Furthermore, in the class My_Dogs I defined the getDetails method.
The object my_dogs will inherit all the properties/methods of the Dogs class plus its own.
Finally, you can notice in the logs that the prototype of My_Dogs class is the Dogs class.
Summary
Let’s summarize what you have learned so far
- For every Javascript object, there is a hidden built-in prototype property
- Each object inherits all the properties and methods of its prototype
- You can modify the prototype object of an object to share properties and methods between objects
- The Javascript engine walks through the Javascript prototypes chain in order to access a property or method for an object until the prototype equals the null object
- you can use the shadowing technique to override a property or method of a prototype
- you can implement inheritance with Javascript prototypes in various ways using object literals, the Object.create method, the constructor method, and the ES6 class method
Happy coding!