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.
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
.
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)
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)
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:
Hello
Code 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
.
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:
30
Code 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)
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.
No comments so far
Curious about this topic? Continue your journey with these coding courses: