JavaScript Coding
JavaScript Languages

JavaScript – Prototypes and Inheritance in JavaScript

Hi everyone, welcome to another tutorial, today we will talk about Prototypes and Inheritance in JavaScript, it is very important to know what Prototype is and how we can work with them. We will see some best practices and how to create an inheritance between objects using Prototype.

First, let us understand what JavaScript is, JavaScript is a Prototype-Based Language, but what does it mean? Let us start understanding the difference between a Class-Based Language and a Prototype-Based Language:

  • Class-Based Language - It is a style of Object-Oriented Programming, a Class-Based Language uses Classes as models for the objects, inside the Class we have the properties and methods. All the objects in a Class-Based Language are instantiated based on Classes and the inheritance is created between Classes, each Class extends another Class.
  • Prototype-Based Language - It is also a style of Object-Oriented Programming, although it does not use Classes, a Prototype-Based Language only uses Objects. For example, in JavaScript we have the Constructor Function, but it is just a method which creates and returns a new Object, it is not a Class! Another thing to take care is about the ES6 Classes, it is not a Class, it is just a syntactic sugar for the Constructor Function. The inheritance in a Prototype-Based Language is created between Objects using Prototype, every object has a Prototype property which indicates its inheritance.

As you understood the idea about Prototype-Based Language, we can take a look on the example below:

Look at this example, we have created an Empty Object called obj1, then we tried to display the name property, obviously, it returned undefined, because we do not have a name property in obj1. But, now look at the line 6, we have created a new Object with the name property and we kept it in the obj1's __proto__ property, however what is the __proto__ property?

This property is the prototype of our Object, so when we put an Object in __proto__, we are creating an inheritance in a JavaScript. Now, in the line 8 we try to display the name property again and the output was "obj2". This happens because JavaScript tries to get the name property from obj1, however obj1 does not have this property, so JavaScript searches the property on the prototype until it finds or when it arrives on the end of the prototype chain.

Now, if we add the name property in obj1 like we did in the line 10, when we try to display it, it shows the obj1's name property and does not show obj1's prototype's name property. With this example, you understood how an inheritance works in a Prototype-Based Language.

Constructor Functions

Constructor Functions are the most used and more recommended way to create new Objects in JavaScript, the example below shows us how to work with prototypes when using Constructor Functions:

To access the Function's Prototype we have the prototype property, when we create an Object from a Constructor Function, the Object's __proto__ has the same reference of the Constructor Function's Prototype, as we can see on the line 8. So, every change we make on the Person's Prototype will affect all the objects which were instantiated based on it.

Problems with prototype

When we are working with Prototype, we must be careful, especially when we are manipulating objects. As we already know, a Prototype-Based Language uses objects to create inheritance. Suppose we have a Constructor Function called Person that has a names array on its Prototype, if we instantiate two new objects (person1 and person2) based on Person and on the person1 we add a new element on the names array, then we will change the Prototype's array, to understand it better, let us see this example:

Look at the line 12, we are adding a new element to the names array, person1 does not have a names property, its Prototype has this property, though. But the person1's Prototype is shared between all Objects which were instantiated based on the Person, if we add the element on it, we are going to affect all instances, as we can see on the lines 14 and 15.

It is pretty simple to fix this problem, we just have to create a names array for each instance instead of creating it on the Person's Prototype. Then, when we change it, only the object's array will be changed, like this example:

It is the enough to fix our problem, This problem will happen every time we try to change an Object that is owned by the Object's Prototype, be careful when using Objects in the Prototype.

Prototype improves Memory Usage

Using prototype is a good way to improve the Memory Usage, let us suppose we have an Object which has a name property, we want to create a Getter Function to return the name property. It is easy, we can write something like the code below:

It is not wrong, but there is a Memory Usage Problem here. When we create a function inside the Constructor Function we are creating a new function for every instance of Person, we can see it on the line 12, we are comparing if person1.getName and person2.getName to see if they have the same reference, however they are different, so we have 2 instances of getName here.

If person1.getName and person2.getName do the same thing, why do not we just create a getName function in the Person's Prototype to keep only one instance of this function? We are able to do it just writing a code like this:

This code creates a getName Function inside Person's Prototype, now when we compare person1.getName and person2.getName they are equal. This is an example of how we can improve the Memory Usage with Prototype.

Inheritance

Inheritance in JavaScript is simple to implement, first we will use what we learned about Prototypes to make the inheritance, and then we will use a technique to call the Super Function using the call function from the Function's Prototype. This link explains more about this function.

We are going to create two Sub Constructor Functions called Dog and Cat which will extend the Super Constructor Function called Animal. The Animal is going to have 2 properties (age and name), each property will have a Getter Function, let us write it:

Our Animal Function and its Sub Functions are done. Let us understand what was done here:

  • Line 1 to 12 - We created the Animal Constructor Function with its properties (age and name) and Getter Functions.
  • Line 14 to 19 - The Dog Constructor Function is created, with a call to Animal Constructor (Line 16) and setting an Animal Object as the Dog's Prototype.
  • Line 22 to 27 - On these lines, we did the same as we did with the Dog Constructor Function, but with the Cat Constructor Function.

Now, we are going to use the instanceof operator to check if Dog and Cat are Animal's children. Basically, the instanceof operator checks if the right Constructor Function's prototype appears on the left object's Prototype Chain, returning true or false.

As we can see, our inheritance is working fine, both Cat and Dog are children of Animal. On this tutorial we learned a important JavaScript subject, using Prototype we are able to create amazing structures and even improve the performance. We also saw about things we must take care about when using Prototypes.

This tutorial finishes here, if you have any doubt or suggestions about what we discussed, feel free to contact us on this email, we will be happy to hear of you!

See you on the next tutorial!!