You are on page 1of 25

JavaScript Prototype and Prototype Chain explained.

In this article, I’m trying to explain some of the core concepts

in the JavaScript related to the Prototype and Prototype Chain.

Before deep dive into those concepts let’s see what is the

requirement of having Prototypes in JavaScript.

Why we need Prototype

Let’s look at the following example where you need to create a

person object in your JavaScript program.

let person = {};

person.name = 'Leo';

person.age = 20;person.eat = function () {


console.log(`${this.name} is eating.`)

}person.sleep = function () {

console.log(`${this.name} is sleeping.`)

Then think of a scenario where you might need more than one person

in your program, what would you do in that case? You would create

a separate function which will generate a Person object for you.

Isn’t it?

Something like this??

function Person(name, age) {

let person = {};

person.name = name;

person.age = age; person.eat = function () {

console.log(`${this.name} is eating.`)

} person.sleep = function () {

console.log(`${this.name} is sleeping.`)
} return person;

}// Invoke Person function to create persons.

const person1 = Person('Mike', 23);

const person2 = Person('Alis', 34);

That is great right? But is this the correct way to do

that?

No, Think of another scenario where you building a more complex

application and there you would need millions of such Person

objects, in that case at each time we create a Person object it

will recreate eat  and sleep methods in the memory. Which eats your

memory.

Instead of doing something like above, what if we can create those


methods once and reuse them as references inside the Person

function. In that way, we will create those methods only once in

the memory. See the example below.

const PersonMethods = {

eat = function () {

console.log(`${this.name} is eating.`)
},

sleep = function () {

console.log(`${this.name} is sleeping.`)

}function Person(name, age) {

let person = {};

person.name = name;

person.age = age;

person.eat = PersonMethods.eat;

person.sleep = PersonMethods.sleep; return person;

According to the above example, we have created a Person methods

object once in the memory and at each time when we are creating a

new Person, we are giving them the reference to that PersonMethods

object’s methods. That way we have resolved the memory issue we

had.
Wow, that is great right? Are we done?

No, Again this method also has some drawbacks. Can you guess?

Were you able to guess the issue with this code? If not don’t

worry let me explain the downside of this code. Let’s assume that

later we decided to add a new method to the Person, what would you

do? Then we have to add that method to the PersonMethods and then

we have to modify the Person function to reference that newly

introduced method as follows.

const PersonMethods = {

eat = function () {

console.log(`${this.name} is eating.`)

},

sleep = function () {

console.log(`${this.name} is sleeping.`)

},
walk = function () {

console.log(`${this.name} is walking.`)

},

}function Person(name, age) {

let person = {};

person.name = name;

person.age = age;

person.eat = PersonMethods.eat;

person.sleep = PersonMethods.sleep;

person.walk = PersonMethods.walk; return person;

Hmm, that is not a major issue, but isn’t it great to have a

common place where we can do changes like above and reflect those

changes on all the created instances? Without having to modify all

the created instances. Instead of doing something like above. That

is where the Prototype comes into the picture in the JavaScript.


Prototype

Prototype is basically a property of a JavaScript function. At

each time we create a function in JavaScript, JavaScript engine

adds an extra property called prototype to the created function.

This prototype property is an object (called as prototype object)

has a constructor property by default. This constructorproperty

points back(i.e blue arrow) to the function object on which

the prototype object is a property. Following diagram illustrates

what I described above.

prototype property points to the Prototype object of the

function(i.e green arrow). We can access the function’s prototype

property using the syntax functionName.prototype. and from the

Prototype object of a function, we can again access the function


object back by functionName.prototype.constructor. If you are

still confused let’s write few codes to understand this.

Creating objects using constructor functions

Hope now you have a slight idea about what prototype is, before

dig into more on this topic let’s first understand one small

concept in JavaScript. That is constructor functions. Please read

my article on Constructor functions in order to have a solid idea

about what is a constructor function and what it does.


Now, Let’s write a construction function which

accepts name and age as function parameters as follows and logs

out its prototype object:

function Person(name, age) {

this.name = name;

this.age = age;

console.log(Person.prototype)

You will see a console output as follows :

As you can see in the above when we console

log Person.prototype it has logged out the created function’s

prototype object. And there we can see two

attributes constructor and __proto__ properties. (For the moment

forget about this __proto__ property in the function’s prototype

object. ) Then let’s logs out the Person.prototype.construcor

See, it looks like the function we defined a few second ago. As I

described above when we create a function, it creates another


object called prototype object which has a constructor property

which points back to the function object and the function itself

has a property called prototype which points to the function’s

prototype object. Let’s see whether those points are correct. If

those statements are correct then the identity operator (===) in

JavaScript should be

evaluated true for Person.prototype.constructor ===

Person  and Person.prototype ===

Person.prototype.constructor.prototype  cases.

As we expected those gives true for the above cases. Which means

whatever the things I described above are correct. I hope now you

have a proper understanding of what is the prototype in

JavaScript.

Now let’s see how we can use above mentioned prototype object to

solve the issue we had earlier. Let’s see what happens if we put
all our custom functions into the prototype object instead of

creating a separate object for those and assign them inside the

function definition as follows :

function Person(name, age) {

this.name = name;

this.age = age;
}Person.prototype.eat = function () {

console.log(`${this.name} is eating.`)

}Person.prototype.sleep = function () {

console.log(`${this.name} is sleeping.`)

}Person.prototype.walk =function () {

console.log(`${this.name} is walking.`)

Then let’s create a new Person called Bob and logs out the Bob as

follows :

Ohh no!!, there are no methods available under the

names eat, age and walk. Isn’t it?

Well, that is not the case, remember what we learned earlier and

what we did? We added those methods to the function’s prototype

object. And as you can see there is something interesting has

happened.
There is another property in the Person instance Bob (i.e

__proto__), but we did not add that property to the object we

created right? So what is it? Basically, this __property__  is

the getterand setter to the function's prototype object. Okay I

know this sounds confusing, let me explain this in simple terms.

Let’s look at what we did to our constructor function :

• First, we defined our constructor function Person.


• Then we added methods to its prototype object.

When we add functions or properties (you also can add

properties) to the any function’s prototype object it will

be available to its instances through the prototype

object.

Then let’s look at what happened when we creating the instance

from the Person constructor function.

• We created an object called Bob with two attributes using the


Person function with the new  keyword.

• Then behind the scene from the JavaScript engine, it adds a new
property called __proto__ to that instance which is a
getter/setter for the above Function’s prototype object.
• (Hope you read my article on Constructor Functions in
JavaScript if you are not familiar with JavaScript constructor
functions.)

That is what happened from the above code we wrote. And let me

illustrate those in a simple diagram which lets you understand

those very easily.


So basically if the __prototype__ property in the Bob is point to

the Prototype object of the Person constructor function object,

then it should have those methods we defined. To see that let’s

expand that __prototype__ property in the Bob.

If all the things we discussed are correct then prototype property

(__proto__) in the Person instance Bob pointing to the same object

of the Person construction function’s prototype object. We can

evaluate using the identity operator as we did before.

Yes, we were correct. Object instance prototype property (i.e

__proto__) and Function’s prototype property pointing to the same


object. Now let’s create another instance of Person and let’s see

whether that instance’s pointing to the same prototype object.

As we can see in the expanded console output, it looks like new

instance’s prototype property also pointing to the same object. If

that is true then identity operator evaluation for Alex.__proto__

=== Bob.__proto__ and Person.prototype === Bob.__proto__ should be

evaluated to true. Let’s see.

Yes, it is Alex’s prototype property (i.e __proto__)also pointing

to the same Object as the Alex prototype property (i.e __proto__).

Which gives a relationship as depicted in the following diagram.


So as a summary we can point out what we learned.

• When we create a function, JavaSctipt engine automatically


creates a Prototype object for that function and
add prototype property to Function object which can be used to
access that Prototype object, as well as it
adds constructor property which points back to the Function
object.
• Then when we create instances from the Function object, then
again JavaScript engine adds add getter/setter (i.e
__proto__) to object’s instance which can be used to access the
same prototype object of the Function object.
• This Prototype object of the constructor function is shared
among all the objects created using the constructor function.
We can add methods and properties into this prototype object
and then those automatically will be available to its
constructor function ’s instances.

NOTE: This __proto__ usually called it as dunder proto in

the JavaScript world.

Hope you have a solid understanding of what is known as Prototype

in JavaScript. Next will have a look at the Prototype chain.

Prototype Chain

By now you should have a solid understanding of what is

Prototype  in JavaScript, next will try to understand what

is Prototype Chain.  In order to understand that let’s do a small

exercise. Let’s create a simple object and then alert the object.

Alert output as follows:

Okay, how on earth we get this [object Object] from the alert as

an output? appleis an empty object and it does not have any

properties which hold such data or function which can generate

something like that. It seems like something has happened behind

the scene. Let’s dig this bit further. First, let’s console out

the apple and see whether we can find anything there.


Oh, there is nothing in it, but if we expand the apple object we

can see __proto__property in it. Okay cool, that’s interesting.

This gives us a hint that this is pointing to a some function’s

prototype object. Let’s console log that and see whether we can

find anything from that.

Ohh, There are lots of functions on it. But where this is coming

from? and Whose prototype object is this? And there is

a toString()  function on it. To my sense, it feels like that

output we saw from alert might have generated from this method.

Let’s see.

Yes, it is!!!! Finally, we found out how we go that output from

the alert. That is when we alerting that apple object, the

JavaScript engine has called this toStringmethod in some object’s

prototype object’s function in order to generate this output. Then


we have another unresolved mystery. That is, whose prototype

object is this?

In JavaScript, there are set of built-in Objects such

as Object, Array, Date, Function etc and each of those objects

will have respective prototype objects attached to it.

In the above case, it was the Object construction function which

invoked to create the apple instance. That is because const apple

= {}  is the same as const apple = new Object() where Object is the

built-in constructor function.

And that function has Object.prototype, which has all the methods

we saw earlier. If what we found out true then we can use the

identity operator (===) to evaluate the facts that we are familiar

with.

If Object constructor function was invoked when creating the apple

instance then Object.prototype and apple.__proto__ should point to

the same prototype object.

Yeah, we were correct. Those were pointing to the same prototype

object. And also following will also be obviously true if that

prototype object belongs to the Object constructor function

Object.

Let me draw a simple relationship diagram to show what we

discussed :
Also please note that unlike other function’s prototype object,

Object function constructor’s prototype object does not have

a __proto__ property inside it. If we console log its value, it

should be null.

To understand the reason for this; first, we need to have an

understanding of object lookup behavior in JavaScript. When we

look for a property of an object (including function

declarations), the JavaScript engine will first check the object

itself for the existence of that property.

If not found, it’ll go to the object’s prototype object and check

that object. If found, it’ll use that property. If that is not

found in that object then it will lookup on that prototype

object’s prototype object, If found it there, it’ll use that

property or else lookup continues until it finds an object with

a __proto__ property equal to null.

That is the JavaScript built-in object’s prototype object. Here it

has set to null in order to terminate the prototype lookup chain.


This is called the prototype chain. This is why we

see undefined for the values which are not defined in the any of

the prototype type chain objects.

Please Note [extracted from  MDB Web Docs:

Following the ECMAScript standard, the

notation someObject.[[Prototype]]is used to designate the

prototype of someObject. Since ECMAScript 2015,

the [[Prototype]]is accessed using the

accessors Object.getPrototypeOf()  and Object.setPrototypeO

f().

This is equivalent to the JavaScript

property __proto__which is non-standard but de-facto

implemented by many browsers.

It should not be confused with the func.prototype property

of functions, which instead specifies the [[Prototype]] to

be assigned to all instances  of objects created by the

given function when used as a constructor.

The Object.prototype property represents

the Object prototype object.

Let me put all of these into a simple relationship diagram which

lets up to grasp this easily.


Also, other built-in Objects such as Array, Date, Function etc

also has an associated prototype and those have all additional

methods which are specific to that type.

For an instane, if we create a simple number array [1, 2, 3], the

default new Array()  constructor function get invoked internally,

from the behind the scene by the JavaScript engine.

And also JavaScript will add a __proto__ pointer to newly created

array instance which points to the Array. prototype

(i.e Array.prototype) object which has all the methods relevant to

the Array operations such as concat, reduce, map, forEachetc.


And also if we log the newly created array instance prototype

object’s prototype (i.e numArray.__proto__.__proto__) we can see

that it has a pointer to another object, which should be

the Object.prototype.

Yes, it seems correct, as we did before let’s evaluate few

expressions with identity operator to check whether what we

learned is correct.
By specification, all built-in Objects in JavaScript has

prototype Object associated with it and it points to the

Object.prototype object. That is why many people

say “Everything in JavaScrtipt is inheriting from Object.”

There are few other things which I want to point out related to

the prototype chain in JavaScript, that is method override.

As we learned so far every object we create inherits its methods

and properties from its prototype objects chain. And also we

should know that we can override those methods as the way we want.

Let’s look at the following console output.

when we are logging out the number array that we created we can

see a nicely printed values array. How is this possible? That is

because Array.prototypeobject has a custom toString() method

implementation to do this.

So when we are console.log this array from the JavaScript engine,

behind the scene calls that method. But as we

learned Object.prototype object also has a toString()method.

But for the created numArray instance the closes method it fined

when looking up the toString( ) function along the prototype chain

it will be the Array.prototype object’s toString() method. Hence


engine will use that method to print out the elements in the array

to console output.

All the other built-in objects also work the same way. Such as

Functions, Date etc.

Prototype with Primitives

Next thing I want to highlight is the prototype

with Primitives.  It is the most intricate thing happens when it

comes to the prototypes. As we know those are not objects in the

JavaScript, But when we try to access their properties JavaScript

engine will automatically create a temporary wrapper object

creates using built-in constructor function such as String,


Number, Boolean, Symbol(ES6)except for the null and undefined.

Those will provide additional methods to use with primitives.

Those objects created under the hood by the JavaScript engine and

will not be visible to us. Many JavaScript engines such as V8,

SpiderMonkey has their own optimizations to that as well.

Values null and undefined have no object wrappers. Those will

stand apart as special values in JavaScript when it comes to the

primitives.

Since they do not have object wrappers, simply they will not have

additional methods and properties for them and also they don’t

have any associated prototype object too.

So far we have learned quite a lot about

JavaScript Prototype and Prototype Chain , Now let’s put all of

our understandings into one big diagram to recap everything we

learned.

Hope I have covered everything related to the JavaScript Prototype

and Prototype Chain. If you have any questions related to these


concepts, feel free to ask anything in the comment section.

Cheers!!

You might also like