Understanding Prototypal Inheritance In JavaScript
Tags: javascript, tutorial, webdev, showdev
Published: 2020-04-23 11:38:02

---
title: Understanding Prototypal Inheritance In JavaScript
published: true
description: Explaining prototypal inheritance in JavaScript to the last detail
tags: Javascript, tutorial, webdev, showdev
series: OOP (Object Oriented Programming) In JavaScript
cover_image:  https://res.cloudinary.com/drquzbncy/image/upload/v1587572857/js__proto___o8bana.png
---

## Table of Contents
  1. [What Is Object-oriented Programming (OOP)](#chp-1)
  2. [Classical vs Prototypal Inheritance](#chp-2)
  3. [The Prototype Object And The Prototype Chain](#chp-3)
  4. [Exposing ***this*** Keyword in JavaScript](#chp-4)
  5. [JavaScript Base Object, The Prototype Of All Prototypes](#chp-5)
  6. [The Power Of Prototypal Inheritance](#chp-6)
  7. [Closing Thoughts](#chp-7)

#### 1. What Is Object-Oriented Programming (OOP) <a name="chp-1"></a>
Object-oriented programming is a programming paradigm that involves organizing codes into object definitions. These are sometimes called classes. 

In object-oriented programming, we use objects to model real-world things that we want to represent inside our programs. These objects can contain (***encapsulate***) related information which is the properties and methods (functions) stored in the objects. These are often the properties and behaviours of the real-life object we are modeling.

#### Classical vs Prototypal Inheritance <a name="chp-2"></a>
JavaScript is a very unique, beautiful, sometimes weird, and incredibly powerful programming language. Object-oriented JavaScript uses prototypal inheritance. Here we find JavaScript making popular a concept that is in many ways better than what is already in use in other programming languages like Java, C#, and C++ (***Classical inheritance***).

The classical inheritance or class bases inheritance involves writing classes; these are like blueprints of objects to be created. Classes can inherit from classes and even create subclasses. This method is solid and battle-tested as it is what powers many popular programming languages like Java and C++ as mentioned above but it has its downside.

One of the downsides of classical inheritance is that it is very verbose and you can quickly end up with a huge mass of collection and trees of objects that interact, that it can become very hard to figure out what is going on even if you use good practice. Plus you would have to learn and use a lot of intimidating keywords viz: ***friend, protected, private, interface, etc***.

> *The class keyword, however, has been introduced to JavaScript in ES2015, but it is just syntactical sugar,* ***JavaScript remains prototype-based***

Prototypal inheritance is a much simpler approach. It is flexible, extensible, and very easy to understand. *It is not a silver bullet anyway* but it is in many ways better than class-based inheritance and it would be our focus going forward.

#### 3. The Prototype Object And The Prototype Chain <a name="chp-3"></a>
To understand prototypal inheritance we need to understand these three key concepts viz: *inheritance, prototype, prototype chain*
Inheritance refers to a process whereby one object gets access to the properties and methods of another object. 
Let's deal with these keywords with examples.

*Remember in OOP we use objects to model real-world things that we want to represent inside our programs*

{% runkit %}
const AppleInc = {
    name: "Apple",
    logo: "Apple fruit",
    operating_system: "Apple Software",
    on () {
       console.log("Turning on your " + this.name + " device")
    },
    off () {
       console.log("Turning off your " + this.name + " device")
    }
    
}
console.log(AppleInc)
{% endrunkit %}

In the small contrived example above I have modeled the Apple company. It has a *name, logo, and operating_system* property, both an ***on()***, and ***off*** methods(which are functions, meant to describe the behaviours of Apple devices). 

We will proceed to model some products of Apple and have them inherit these properties. 

> All Apple products are unique and each reflects the image of the company. 
You can certainly tell it is an Apple product even without seeing the logo; thus we can say in real-life, each Apple product inherits properties like design, operating system, etc from the company. 

*We will try to express this concept in codes as we demystify prototypal inheritance*

{% runkit %}
const AppleInc = {
    name: "Apple",
    logo: "Apple fruit",
    operating_system: "Apple Software",
    on () {
       console.log("Turning on your " + this.name + " device")
    },
    off () {
       console.log("Turning off your " + this.name + " device")
    }
    
}

const iPhone = {
    name: "iPhone",
    operating_system: "ios"
}

console.log(iPhone) 
iPhone.\_\_proto\_\_ = AppleInc // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE
console.log(iPhone) // logs iPhone with AppleInc as its prototype.
console.log(iPhone.on())
console.log(iPhone.off())
{% endrunkit %}

> Kindly run the program in runkit by clicking the green run button to the right and click open the result of each ***console.log()***. 
You would see an image like this:

![alt console.log() result](https://res.cloudinary.com/drquzbncy/image/upload/v1587582767/Screenshot_2020-04-22_at_20.07.53_eyuey2.png)

Notice at the first ***console.log()*** iPhone does not have a ***proto*** object property. But after we assigned AppleInc as its prototype, in the second ***console.log()*** we can see a ***proto*** property, which is the AppleInc object.

Modern browsers allow us to set an object's prototype like this:
```js
iPhone.__proto__ = AppleInc // sets AppleInc to be the prototype of the iPhone object.
```

> :boom: *Kindly note, I am setting this just for demonstration purposes. Do not set your object's prototype like this. [Read more from MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto)*

> :sparkles: *I would also be writing about the recommended ways to set an object's prototype in JavaScript in the upcoming articles in this series*

We can also notice that somehow we could call the ***on()*** and ***off()*** methods from our *iPhone* object. (But they are not originally there!).

We can see that the *iPhone* object has ***inherited*** the properties and methods of its ***prototype object.*** (An object from which another object inherits properties and methods. It lives as a property in that object with the name ***\_\_proto\_\_***

As a result of this, we can call the ***on()*** and ***off()*** methods even when they are not originally in the *iPhone* object. This is possible because JavaScript holds a reference to the prototype of the *iPhone* object and when we try to access a property or method, it looks for it in the *iPhone* object first, and if it cannot find it there, it goes to its prototype (**The \_\_proto\_\_ object property as seen**) and looks for it there. 
*It returns the property or method once it finds it and stops the search.* 

This explains why: 
```js
iPhone.name // returns iPhone and not Apple
```

{% runkit %}
const AppleInc = {
    name: "Apple",
    logo: "Apple fruit",
    operating_system: "Apple Software",
    on () {
       console.log("Turning on your " + this.name + " device")
    },
    off () {
       console.log("Turning off your " + this.name + " device")
    }
    
}

const iPhone = {
    name: "iPhone",
    operating_system: "ios"
}

iPhone.\_\_proto\_\_ = AppleInc // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE
console.log(iPhone.name)
{% endrunkit %}

The JavaScript engine finds the name property in the *iPhone* object returns it, and ends the search. 

In JavaScript, a prototype can have its own prototype. So the *AppleInc* object can have its own prototype which can, in turn, have its own prototype and the process can go on. So when the JavaScript engine looks for a property or method in an object and cannot find it, it would go to its prototype and look for it there, if it does not find it, it would go to the prototype of that prototype and continue to go down the ***prototype chain*** until it finds it. 

> *This chain of links or object references between an object, it's prototype, and the prototype of its prototype all the way down to the last prototype is called the prototype chain*

{% runkit %}
const Company = {
    category: "Technology"
}

const AppleInc = {
    name: "Apple",
    logo: "Apple fruit",
    operating_system: "Apple Software",
    on () {
       console.log("Turning on your " + this.name + " device")
    },
    off () {
       console.log("Turning off your " + this.name + " device")
    }
    
}

const iPhone = {
    name: "iPhone",
    operating_system: "ios"
}

AppleInc.\_\_proto\_\_ = Company // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE
iPhone.\_\_proto\_\_ = AppleInc // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE
console.log(iPhone.category) // gets this from the search down the prototype chain
{% endrunkit %}

Run the code above and see that we can access the category property even from the *iPhone* object because of the *search down the prototype chain.*

#### 4. Exposing ***this*** Keyword in JavaScript <a name="chp-4"></a>
You might be surprised by this title, but I see an opening in this post to deal a little on the ***this*** keyword which has a reputation of being confusing in our beautiful language; JavaScript. 
Let's visit our example again:

{% runkit %}
const AppleInc = {
    name: "Apple",
    logo: "Apple fruit",
    operating_system: "Apple Software",
    on () {
       console.log("Turning on your " + this.name + " device")
    },
    off () {
       console.log("Turning off your " + this.name + " device")
    }
    
}

const iPhone = {
    name: "iPhone",
    operating_system: "ios"
}

iPhone.\_\_proto\_\_ = AppleInc // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE
console.log(iPhone.on())
console.log(iPhone.off())
{% endrunkit %}

From our code above we understood that we are able to call the ***on()*** and ***off()*** methods from the *iPhone* object because of JavaScript's prototypal inheritance. (where we explained *inheritance, prototype, and the prototype chain*). 
But why does this work correctly?
```js
console.log(iPhone.on()) // returns Turning on your iPhone device
console.log(iPhone.off()) // returns Turning on your iPhone device
```
How does it know the correct name is *iPhone* when the method is actually on the *AppleInc* object which is the prototype of the *iPhone* object and has its own name property? 
It is because of the ***this*** keyword. It is pointing to the *iPhone* object; thus it gets the name property from it.

>*Take note, the* ***this*** *keyword in cases like this, starts its search from the object that originates the call, and since it found the name property in the iPhone object it points to it there.*

Hold unto the above *rule of thumb* as we take a deeper look at ***this*** below:

> The ***this*** keyword is a very interesting aspect of JavaScript it is extremely powerful and can sometimes be a little confusing. Below is the general *rule of thumb* to help you further understand the behaviour of the ***this*** keyword.

Kindly run the example code below and consider the result. 
{% runkit %}
// New additions
let name  = "Brendan Eich"

function sayName() {
 console.log(this.name) 
}

let Person = {
   name: "Lawrence Eagles",
   sayName() { console.log(this.name) }
}

sayName()
Person.sayName()
{% endrunkit %}

From the result, we can see that when you use the ***this*** keyword in a function it points to the global object but when you use it in a method (a function inside an object), it points to that object.
Following this, let's return to our code. I have added some extra properties to help us understand the ***this*** keyword better and consequently, understand our example more thoroughly.
*Kindly run the code below and consider the results.*

{% runkit %}
const Company = {
    category: "Technology",
    getNews () {
       console.log("viewing " + this.category + " news on my " + this.name + " device")
    }
}

const AppleInc = {
    name: "Apple",
    logo: "Apple fruit",
    operating_system: "Apple Software",
    store: "Apple Store",
    on () {
       console.log("Turning on my " + this.name + " device")
    },
    off () {
       console.log("Turning off my " + this.name + " device")
    },
    getDevice() {
       console.log("I just bought my " + this.name + " from " + this.store)
    }
}

const iPhone = {
    name: "iPhone",
    operating_system: "ios"
}

AppleInc.\_\_proto\_\_ = Company // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE
iPhone.\_\_proto\_\_ = AppleInc // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE

// let's buy an iPhone from the Apple store, then let's turn on and off our iPhone.
console.log(iPhone.getDevice())
console.log(iPhone.on())
console.log(iPhone.off())
console.log(iPhone.getNews())
{% endrunkit %}

From the result of the code above we see that when we ran the method to buy an iPhone,
```js
console.log(iPhone.getDevice()) 
// returns I just bought my iPhone from Apple Store
```
the ***this*** keyword points to different objects to get the correct property. It starts by pointing to the object that originates the call and since it can find ***name property*** in the *iPhone* object it points to that. But it cannot find the ***store property*** in the iPhone object so it points to its prototype and looks for the property there and finds it.
This same principle holds when we tried to turn on/off our iPhone.
```js
console.log(iPhone.on()) // returns Turning on my iPhone device
console.log(iPhone.off()) // returns Turning off my iPhone device
```
Here the ***this*** keyword starts searching from the object that originates the call and because it can find the ***name property*** in it, it points to it there. Thus we get the correct device name even though the ***on()*** and ***off()*** methods are not in that object but in their prototype. 
Finally, the result is the same when we try to read news from our iPhone device,
```js
console.log(iPhone.getDevice()) 
```
Notice the ***getDevice()*** method is in the *Company* object which is the prototype of the *AppleInc* object which is the prototype of the *iPhone* object. And because of the prototype chain, we can call ***getDevice()*** from the *iPhone* object as if it just sits in it. 

Let's move forward.

#### 5. JavaScript Object, The Prototype Of All Prototypes <a name="chp-5"></a>
When I said the JavaScript engine looks in an object for a property and if it cannot find it, it keeps going down the prototype chain until it finds it; you might have wondered what will be the last prototype? 
Like in our case, what would be the prototype of the *Company* object?
Kindly run the code below and consider the result.

{% runkit %}
const Company = {
    category: "Technology"
}

const AppleInc = {
    name: "Apple",
    logo: "Apple fruit",
    operating_system: "Apple Software",
    on () {
       console.log("Turning on your " + this.name + " device")
    },
    off () {
       console.log("Turning off your " + this.name + " device")
    }
    
}

const iPhone = {
    name: "iPhone",
    operating_system: "ios"
}

AppleInc.\_\_proto\_\_ = Company // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE
iPhone.\_\_proto\_\_ = AppleInc // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE
console.log(Company.\_\_proto\_\_) // gets this from the search down the prototype chain
{% endrunkit %}

You can see that the prototype of the *Company* object is the *built-in JavaScript object.* Since in Javascript everything is an object, all the other data types in JavaScript inherit properties and methods from the base object. So it is the final prototype in JavaScript.

***Kindly open up the console.log() result of the code below from runkit and you would see something like this:***
![object prototype image](https://res.cloudinary.com/drquzbncy/image/upload/v1587589187/Screenshot_2020-04-22_at_21.59.30_te5exx.png)
Notice some familiar names like the *[hasOwnProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty) and the [isPrototypeOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf) methods, [the constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor) etc*

So the base object in JavaScript is the prototype of all data types in JavaScript, be it arrays, strings, numbers, functions, etc. 

> *All data types in JavaScript have a prototype object that inherits its property and methods from the base object. Let's look at some of them in the next section.*

#### 6. The Power Of Prototypal Inheritance <a name="chp-6"></a>
Welcome to the power of prototypal inheritance. I am sure you would have already seen how flexible, extensible, and how easily objects can share properties and methods when using prototypal inheritance.

Let's look at some code examples for more:
***Kindly run the codes below and open up each console.log() in runkit***
{% runkit %}
const simpleArray = []
const simpleFunction = function simpleFunction () {}
const simpleString = ""

console.log(simpleArray.\_\_proto\_\_)
console.log(simpleFunction.\_\_proto\_\_)
console.log(simpleString.\_\_proto\_\_)
{% endrunkit %}

If you open up the first *console in runkit* you would notice that it has an ***Array Prototype*** which have a huge collection of properties and methods as seen in the image below.
![alt Array prototype properties](https://res.cloudinary.com/drquzbncy/image/upload/v1587590157/DEV.TO/Screenshot_2020-04-22_at_22.15.36_j0dzyu.png)
Notice some familiar names here viz: *concat(), every(), filter(), find(), pop(), map(), reduce() etc you can scroll up or down on runkit for more of them.* 
These are methods we use every day in JavaScript when we implement our own array. Notice they all sit in the ***Array Prototype Object***. 

>*Think of how much hassle it would be if we would have to write out all these properties and methods every time we create an array in our program!*

If you open up the next *console in runkit*, you would get something like this:
![alt Function prototype properties](https://res.cloudinary.com/drquzbncy/image/upload/v1587590627/DEV.TO/Screenshot_2020-04-22_at_22.23.10_hiff4h.png)
Notice some familiar names like the *call(), apply() and bind()* methods, all present in the ***Function Prototype Object***.
The prototype of all JavaScript functions is called the ***Function Prototype.*** It is actually an *empty function. (a function with nothing in its code "{}" block*

Finally, open up the last *console in runkit* and you would get something like this:
![alt String prototype properties](https://res.cloudinary.com/drquzbncy/image/upload/v1587590807/DEV.TO/Screenshot_2020-04-22_at_22.26.30_ecxa2m.png)

Notice some familiar names like the *length property, the split(), indexOf(), substring() methods and lot's more you can scroll down to see all*

The prototype of all strings in JavaScript is called the ***String Prototype.***

What do you think would be the prototype of all these prototypes viz:
*array Prototype, Function Prototype, and the String Prototype?*
Let's answer this with some more code examples.
Kindly run the codes below and consider the results in the *console in runkit*.

{% runkit %}
const simpleArray = []
const simpleFunction = function simpleFunction () {}
const simpleString = ""

console.log(simpleArray.\_\_proto\_\_) // array prototype
console.log(simpleArray.\_\_proto\_\_.\_\_proto\_\_) // base object
console.log(simpleFunction.\_\_proto\_\_) // function prototype 
console.log(simpleFunction.\_\_proto\_\_.\_\_proto\_\_) // base object
console.log(simpleString.\_\_proto\_\_) // string prototype 
console.log(simpleString.\_\_proto\_\_.\_\_proto\_\_) // base object
{% endrunkit %}

From the above results, it is clear that the prototype of all prototypes in JavaScript is the base object.

We can also see a powerful pattern here. Prototypal inheritance allows us to write our properties and methods in one place and share them with other objects in our application. Hence both the *array, function, and string prototype* contains a huge list of properties and methods that is passed on to every array, function, and string declaration respectively in our program. 

>*This saves us memory and time.*

We can also use this power to create other Apple devices and have them get some properties and methods from the AppleInc object.

{% runkit %}
const Company = {
    category: "Technology"
}

const AppleInc = {
    name: "Apple",
    logo: "Apple fruit",
    operating_system: "Apple Software",
    on () {
       console.log("Turning on your " + this.name + " device")
    },
    off () {
       console.log("Turning off your " + this.name + " device")
    }
    
}

const iPhone = {
    name: "iPhone",
    operating_system: "ios"
}

const iPad = {
    name: "iPad",
    operating_system: "ios"
}

const laptop = {
    name: "mac",
    operating_system: "mac os x"
}

AppleInc.\_\_proto\_\_ = Company // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE
iPhone.\_\_proto\_\_ = AppleInc // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE
iPad.\_\_proto\_\_ = AppleInc // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE
laptop.\_\_proto\_\_ = AppleInc // NEVER DO THIS IN REAL-LIFE. ONLY FOR DEMONSTRATION PURPOSE


// let's turn on and off all our apple devices
console.log(iPhone.on())
console.log(iPad.on())
console.log(laptop.on())
console.log(iPhone.off())
console.log(iPad.off())
console.log(laptop.off())
{% endrunkit %}

#### 7. Closing Thoughts <a name="chp-7"></a>
I do hope you followed through to this point. You are appreciated. It is a pretty long post but I want to believe that you got a thing or two. If you are not clear on any point or you have an addition, in case I miss anything, I would be looking forward to hearing from you in the comment section below.