What is prototype in JavaScript? Prototypal inheritance explained

What is prototype in JavaScript? Prototypal inheritance explained

In this article, we will talk about prototypal inheritance in JavaScript. We will start with the basics of prototype, and prototype chain, and then we will talk about how to use prototypes in JavaScript. This is actually a very core concept and is also a popular interview question. So, let’s get started.

When you let’s say create an array in JavaScript, you will notice that it has a lot of methods.

Methods of array
Methods of array

How does it have these methods? The answer is prototypal inheritance. Before talking about prototypes, let’s talk about inheritance in JavaScript.

Prototypal inheritance in JavaScript

Inheritance in Javascript is very different from other languages like Java or C++. Keep this in mind while you try to understand inheritance for JS and don’t get confused with the classical inheritance. Inheritance in JavaScript is based on prototypes. In other words, JavaScript objects inherit properties directly from other objects.

Prototypes

According to the MDN documentation, “Each object has a private property which holds a link to another object called its prototype“. Let’s take an example and understand this:

Open the console in your browser and type the following:

const person = {
  name: "John",
  age: 30,
  greet: function () {
    console.log("Hello, my name is " + this.name);
  },
};Code language: JavaScript (javascript)

Now, if you type person in the console, you will see the following:

{ name: "John", age: 30, greet: ƒ }Code language: JavaScript (javascript)

Now, if you type person.__proto__ in the console, you will see the following:

{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}Code language: JavaScript (javascript)

As you can see, person has a property called __proto__ which is an object. In this case, it is the same as Object.prototype.

Prototype Inheritance
Prototype Inheritance

Let’s take another example:

let arr = [1, 2, 3];Code language: JavaScript (javascript)

Here we are creating an array. Now if we want to check the prototype of arr, we can do it by typing arr.__proto__ in the console. We will get the following:

(3) [1, 2, 3]Code language: JavaScript (javascript)

You will see it is the same as that of Array.prototype. Let’s take this further and check the prototype of Array.prototype:

arr.__proto__.__proto__Code language: JavaScript (javascript)
Prototype Chain in JS
Prototype Chain in JS

Whoa !! This is the same as Object.prototype. Let’s take it another step ahead and check the prototype of Object.prototype:

arr.__proto__.__proto__.__proto__Code language: JavaScript (javascript)

Now it says it’s null. This is the end of the prototype chain. So, this is how the prototype chain works. Let’s try this out with functions:

function greet() {
    console.log("Hello");
}Code language: JavaScript (javascript)

Now, if we type greet.__proto__ in the console, we will get the following:

ƒ () { [native code] }Code language: JavaScript (javascript)

This is the same as Function.prototype. Let’s take this further and check the prototype of Function.prototype:

greet.__proto__.__proto__Code language: JavaScript (javascript)
Function's prototype chain
Function’s prototype chain

This is the same as that of Object.prototype. So, what can be concluded from this?

“Everything in JS is indeed an Object.”

There is a method called Object.getPrototypeOf() which can be used to get the prototype of an object. You should always prefer this method over __proto__.

Adding properties to the prototype

We can even add properties to the prototype. That way any object that is created using that constructor will have access to those properties. Let’s take an example:

Function.prototype.greet = function () {
    console.log("Hello");
}Code language: JavaScript (javascript)

This will create a new property called greet in the prototype of Function. Now, let’s create a function like we would have created normally.

function sum(a, b) {
    return a+b;
}Code language: JavaScript (javascript)

Now, if we type sum.greet() in the console, we will get the following:

HelloCode language: JavaScript (javascript)

This is because we have added a property called greet to the prototype of Function. So, any function that is created using the Function constructor will have access to this property as well.

Experimenting with prototypal inheritance

Can we update the prototype of an object? Let’s try this out. We will create two objects and then try to update the prototype of one of them with the other.

const person = {
  name: "John",
  age: 30,
  greet: function () {
    console.log("Hello, my name is " + this.name);
  },
};

const employee = {
  name: "Andy"
};

Object.setPrototypeOf(employee, person);Code language: JavaScript (javascript)

With the help of Object.setPrototypeOf(), we can set the prototype (i.e., the internal Prototype property) of a specified object to another object or null.

Now if you type employee. it will show in the prompt that it has access to the method greet() and also the property name. This is because we have updated the prototype of employee with person.

Prototype Updated
Prototype Updated

What would happen if we call the method greet() on employee?

employee.greet();Code language: JavaScript (javascript)

We will get the following:

"Hello, my name is Andy"Code language: JavaScript (javascript)

This is because the prototype of employee is person and person has a method called greet(). Inside greet() we are using this.name which will refer to the name property of the object on which the method is called. In this case, it is employee and employee has a property called name which is Andy.

But, what if we display the property age of employee?

employee.age;Code language: JavaScript (javascript)

We will get the following:

30Code language: JavaScript (javascript)

This is because the prototype of employee is person and person has a property called age which is 30. So, when we try to access the property age of employee, it will first look for it in employee and if it doesn’t find it there, it will look for it in the prototype of employee which is person and it will find it there.

This is how the prototypal inheritance works.

Important thing to note about prototypal inheritance

You cannot make a cycle in the prototype chain. In the previous example itself, we had person as the prototype of employee. If we try to set the prototype of person with employee, we will get an error.

Object.setPrototypeOf(person, employee);Code language: JavaScript (javascript)
Cycle in Prototype
Cycle in Prototype

Conclusion

In this article, we learned about prototypal inheritance and how it works. We also learned how to add properties to the prototype and how to update the prototype of an object.

I hope you enjoyed the article. Feel free to connect with me and follow me @ArnabSen1729.

Sharing is caring

Did you like what Arnab Sen wrote? Thank them for their work by sharing it on social media.

0/10000

No comments so far