How Prototype & its Chain works in JavaScript?

ยท

7 min read

How Prototype & its Chain works in JavaScript?

In my article, Introduction to JavaScript. I explained how JavaScript is a powerful programming language that is widely used for web development. So in this article, we will see one of its key features is the ability to create objects using prototype and prototype chaining. Understanding the prototype concept is essential for writing efficient and effective code in JavaScript, especially when dealing with object-oriented programming. This article is suitable for those who already have a basic knowledge of JavaScript and are interested in exploring advanced concepts in the language

To understand this topic, there are some Prerequisites:

I highly suggest you go through the articles that I've mentioned above before moving forward with this topic. By the end of this article, you will have a comprehensive understanding of prototypes & prototype chains in JavaScript, and how they can be used to create objects and inherit properties.

Prototypes in JavaScript

As we know that everything in JavaScript is an object somehow. And objects have some default properties, which is called prototype. A prototype serves as a template for creating other objects.

In JavaScript, all objects have a prototype, and the properties and methods of the prototype are inherited by the objects that are created from it. This allows for efficient code reuse and reduces the need for duplicating code. To understand it in more depth let's take an example here:-

let's say you have a JavaScript code file. In that code, you have defined some arrays and objects. as shown below:

let myHeros = ["thor", "spiderman"]
let dcHeros = ["batman", "black adam", "superman"]
let heropower = {
    thor: "hammer",
    spiderman: "sling",

    getSpiderPower: function(){
        console.log(`Spidy power is ${this.spiderman}`);
    }
}

When you console them you will see everything will have their prototype as shown in the image below:

This prototype is itself an object therefore it will have its prototype, which will be making some sort of chain and we call it a prototype chain. which brings us to our next topic.

Prototype chain

Prototype-chaining is the mechanism by which an object can inherit properties and methods from its prototype and the prototypes of its prototype. This creates a chain of prototypes, with each object inheriting from the prototype of the object before it. The chain ends when we reach a prototype that has null for its prototype.

How prototype-chaining works:

Whenever we need to access the property of an object or array it will start finding that property within the object or array first and if the property is not there, the prototype is searched for their property. If the property is still not present there, then the prototype's prototype is searched, and so on till it reaches the end of the chain where it has null in which case, undefined is returned.

let's try to see what is happening in prototype chaining

We have an object :

let heropower = {
    thor: "hammer",
    spiderman: "web sling",

    getSpiderPower: function(){
        console.log(`Spidy power is ${this.spiderman}`);
    }
}

We will take two scenarios:-

In 1st scenario, we will call our object's function getSpiderPower, which we've defined:

When we call heropower.getSpiderPower() , the browser looks for getSpiderPower in heropower object and it will find it there (because we have defined it there) and call it.

In 2nd scenario, we will call our object's function which is by default in the prototype of the object.

When we call heropower.isPrototypeOf, the browser looks for isPrototypeOf in heropower object and cannot find it there so looks in the prototype object of heropower for isPrototypeOf and it will find it there (because by default that property is present there in the Objects prototype) and calls it.

What's in the prototype of objects:

To find out what basic properties that are present in the prototype of objects, there is a function that we can use Object.getPrototypeOf() .

Object.getPrototypeOf(heropower);

The above line of code will give us the Prototype of the object heropower as shown in the image below:

Adding function to Prototype:

We can add our function to the prototype and it will available in all their respective prototype. For example: If we add a function to Object's prototype it will be available in all objects' prototypes in our Javascript code file. The same thing will happen with others like Arrays, strings, etc.

Adding function in Object Prototype:

// Syntax
Object.prototype.Yasir = function(){ 
      console.log(`Yasir is present in all objects`);
}

Here you can see in the image below: In the Object's prototype, there is a function that we defined named Yasir .

This function can be accessed from the main object's prototype.

  • If you have so many objects this function will be there in their prototype. In the image below, we call our defined function Yasir using the object heropower

  • And suppose you have an array or string by default it will have a prototype and that prototype also have an object's prototype in that we can find our defined function and access it.

    In the image below, we call our defined function Yasir using the array heropower

Adding function in Array Prototype:

// Syntax
Array.prototype.arrayfunc = function(){ 
       console.log('New function for the array');
 }

Here you can see in the image below: In the Array's prototype, there is a function that we defined named arrayfunc .

After defining the function in the array's prototype we can have access to that function in every array that we will have in our JavaScript code. In the image below, we call our defined function arrayfunc using the myHeros array.

Adding function in String Prototype:

It has the same steps as the array and object does. We will understand this concept with an example of where we are going to build a function, which will give us the true length of the strings (excluding the spaces at the start and end of the string)

String.prototype.truelength = function(){  
  console.log(`true length is: ${this.trim().length}`); 
}
let name = " Yasir      " 
let lastname = ' Ansari'

In the above example, we defined a function in the String's prototype, which will give us the true length of the string. And we have two strings name & lastname.

By default we have length() function in String's prototype, but it gives the whole length including spaces in the string for example, in string name we have a total length of 12 including spaces before and after the word Yasir , but the true length is 5.

Refer to the images below to get a better understanding:

As we saw that Strings also has some properties by default and we can add functions to its prototypes. So it would not be wrong if we say that string is also an Object somehow. To make this statement more strong we are going to call the function Yasir that we have defined in our object's prototype above using the String lastname.

As you can see below image we can able to access Object's prototype function Yasir through our string lastname .

Creating objects using Prototype

To create a new object using a prototype, you can use the Object.create() method. This method takes a single argument, which is the prototype object that the new object should inherit from. For example:

let object1 = {
    Hello: function() {
        console.log("Hello, World!");
    }
};

let object2 = Object.create(prototype);
object2.Hello();  // Outputs "Hello, World!"

In this example, object2 is a new object that inherits the Hello() method from the object1 object. This method can be called on object2 just like it would be called on the prototype.

You can also add new properties and methods to an object using the prototype chain.

For example:

let object1 = {
    Hello: function() {
        console.log("Hello, World!");
    }
};

let object2 = Object.create(object1);

object2.Goodbye = function() {
    console.log("Goodbye, World!");
};

object2.Hello(); // Outputs "Hello, World!"
object2.Goodbye(); // Outputs "Goodbye, World!"

In this example, object2 inherits the Hello() the method from the prototype, but also has its own Goodbye() method.

It's also worth noting that JavaScript has a built-in Object.prototype object, which is the prototype of all objects in JavaScript. This means that all objects inherit properties and methods from the Object.prototype object by default.

Conclusion:

Prototype and prototype chaining are powerful features of JavaScript that allow for efficient code reuse and the creation of complex object hierarchies. With the knowledge of prototypes and prototype chains, you can create objects that inherit properties and methods from their parent objects, thereby reducing the amount of code and increasing the efficiency of your code. This article has provided you with a comprehensive understanding of prototypes and prototype chains in JavaScript and how they work. With the understanding gained from this article, you are now equipped to use prototypes and prototype chains in your projects and create scalable and efficient applications.

Thank you for reading. Feel free to comment on this, if found it useful.

Happy learning.๐Ÿ˜‡๐Ÿ˜‡๐Ÿ˜‡

ย