Inheritance with JavaScript prototypes
Tags: javascript, webdev
Published: 2019-11-22 17:22:34

---
title: Inheritance with JavaScript prototypes
published: true
date: 2019-11-22 16:00:03 UTC
tags: javascript,webdev
canonical_url: https://blog.logrocket.com/inheritance-with-javascript-prototypes/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ihwjtlskviabt91w46ac.png
---
**Written by [Indermohan Singh](https://blog.logrocket.com/author/indermohansingh/)**✏️

 **TL;DR** : In this post, we will look at prototypes and how to use them for inheritance in JavaScript. We will also see how the prototypical approach is different from class-based inheritance.

## Inheritance

[Inheritance](https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)), a prominent feature of a programming language, emerged with the introduction of object-oriented programming languages. Most of these languages were class-based languages. Here, class is like a plan or blueprint and objects are its manifestation. Meaning, in order to create an object, first we have to create a class. Then we can create any number of objects from one class.

Imagine, we have a class that represents a smartphone. This class has features like capturing images, GPS, etc, like any other smartphone. Here’s an example of how to create such a class and an object in C++ :  
 ![cpp class](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/11/cpp-class.png?resize=954%2C726&ssl=1)

We created a class named `SmartPhone` and it has a method named `capturePictures`, to capture images.

Let’s imagine, we need an iPhone class, that would capture images along with some special features like a face ID scan. Here are two possible solutions:

1.  Rewrite the `captureImages` feature along with other common smartphone features, plus iPhone specific features into a new class. But this approach takes more time, effort and can introduce more bugs.
2. Reuse features from the `SmartPhone` class. This is where inheritance comes into play. It’s a way to reuse features from other classes/objects.

Here is how we can inherit `capturePictures` method from the `SmartPhone` class, in our new `Iphone` class, in C++ :

![inherit capturePictures method from SmartPhone class](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/11/smartphoneclass.png?resize=976%2C946&ssl=1)

Above is a trivial example of inheritance. However, it shows that inheritance allows us to reuse code in a way that the resulting program is less error-prone and takes less time to develop.

Here are some important things to know about classes :

1. A class that inherits the feature is called as a child class
2. A class from which features are inherited is called a parent class
3. A class can inherit from multiple classes at once. For instance, class C inherits from class A and class B
4. We can have multiple levels of Inheritance. For instance, class C inherits from class B and, class B inherits from class A

_It’s worth to note that, class in itself is not doing anything. Until you create an object from a class, no work is actually done. We will see why it’s different from JavaScript._

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## What is a prototype?

In JavaScript, all objects have a special internal property which is basically a reference to another object. This reference depends upon how the object is created. In [ECMAScript/JavaScript specification](https://www.ecma-international.org/ecma-262/), it is denoted as `[[Prototype]]`.

Since `[[Prototype]]` is linked to an object, that object has its own `[[Prototype]]` reference. This is how a chain is built (it’s known as the [prototype chain](https://dev.to/codesmith_staff/explain-javascripts-prototype-chain-like-im-five-51p#:~:targetText=For%20those%20familiar%20(or%20not,chain%20is%20a%20linked%20list.&targetText=Each%20object%20has%20a%20private,with%20null%20as%20its%20prototype.)).

> This chain of `[[Prototype]]` is the building-block of inheritance in JavaScript.

### ` __proto__ ` object

To access the object’s `[[Prototype]]`, most of the browsers provide a ` __proto__ ` property.

This is how we can access it:

```jsx
// obj is an actual object
obj.__proto__
```

It’s important to note that, this property is not a part of the ECMAScript standard. It is a de-facto implementation by the browsers.

### Get and set prototype methods

Apart from the ` __proto__ ` property, there is a standard way to access the `[[Prototype]]`.

Here is how we can access the `[[Prototype]]` of an object:

```jsx
Object.getPrototypeOf(obj);
```

There is a similar method to set the `[[Prototype]]` of an object. This is how we do it:

```jsx
Object.setPrototypeOf(obj, prototype);
```

### `[[Prototype]]` and `.prototype` property

We have now discussed `[[Prototype]]`. It’s nothing but a standard notation to designate the prototype of an object. Many developers get it confused with [.prototype](https://javascript.info/function-prototype) property, which is an entirely different thing.

Let’s explore the `.prototype` property.

In JavaScript, there are many ways of creating an object. One way is using a constructor function, by calling it using the `new` keyword like this:

![constructor](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/11/constructor.log-1.png?resize=1262%2C638&ssl=1)

When you console.log the `phone` object, you will see an object with ` __proto__ ` property, like this:

![phone log](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/11/phone.log-1.png?resize=1078%2C682&ssl=1)

Now, if we want to have some methods on the phone object, we can use `.prototype` property on the function, as follows:

![const prototype](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/11/const.proto-1.png?resize=1242%2C506&ssl=1)

When we create the phone object again, we would see the following in the `console.log`:

![phone log](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/11/phone.log-2.png?resize=1078%2C726&ssl=1)

We can see the `isAndroid()` method in the object’s `[[Prototype]]`.

In short, the `.prototype` property is basically like a blueprint for the `[[Prototype]]` object created by the given constructor function. Anything that you declare in the `.prototype` property/object will pop up in object’s `[[Prototype]]`.

As a matter of fact, if you compare the `SmartPhone.prototype` to the phone’s `[[Prototype]]`, you will see that they are the same:

```jsx
console.log(Object.getPrototypeOf(phone) === SmartPhone.prototype);
// true
```

It’s worth noting that, we can also create methods inside the constructor function. Instead, we did it using the function’s prototype. There’s a good reason to do so.

Let’s take a look at the following example:

![prototype log](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/11/prototype.log-1.png?resize=914%2C858&ssl=1)

The problem with this approach is when we initiate a new object. All the instances get their own copy of `methodA`. On the contrary, when we create it on function’s prototype, all instances of the object share just one copy of the method. Which is more efficient.

## What happens when we access a property?

When we access a property either to get or set it, the following happens:

1. The JavaScript Engine looks for the property on the object
  1. If it finds the property, then it gets/sets it
2. Otherwise, the JavaScript Engine checks the inherited property of an object by looking at `[[Prototype]]`
  1. If the property is found, then it gets/sets it
  2. Otherwise, it looks into `[[Prototype]]` of `[[Prototype]]`. This chain ends when either the property is found or there is no `[[Prototype]]` left, which means that we have reached the end of the prototype chain

It’s also worth noting that the end of a normal object’s `[[Prototype]]` chain is built-in `Object.prototype`. That’s the reason why most of the object shares many methods like `toString()`. Because they are actually defined on `Object.prototype`.

## **Various ways of using**  prototypical inheritance

In JavaScript, there is just prototypical inheritance. No matter how we create an object. But still, there are subtle differences, that we should take a look at.

### Object literal

The easiest way to create an object in JavaScript is by using an object literal. This is how we do it:

```jsx
let obj = {};
```

If we log the obj in the browser’s console, we will see the following:

![object prototype](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2019/11/object-proto-1.png?resize=1344%2C858&ssl=1)

So basically, all the objects created with literal notation inherit properties from `Object.prototype`.

It’s also worth noting that ` __proto__ ` object has reference to the constructor function, from which it’s created. In this case, the `constructor` property points to `Object` constructor.

### Using the Object constructor

Another, not-so-common way of creating an object is using `Object` constructor. JavaScript provides a built-in constructor method named `Object` to create Objects.

Here’s how we use it:

```jsx
let obj = new Object();
```

This approach results in the same object as object literal notation. It inherits properties from `Object.prototype`. Since we use `Object` as a constructor function.

### Object.create method

With this helper method, we can create an object with another object as it’s `[[Prototype]]` like this:

![object create](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2019/11/obj.create.png?resize=1098%2C726&ssl=1)

This is one of the simplest ways to use inheritance in JavaScript.

Any guess how we can make an `object` without any `[[Prototype]]` reference?

### Constructor method

Similar to how we have the object constructor function provided by JavaScript runtime. We can also create our own constructor, to create an object which suits our needs as we can see here:

```jsx
function SmartPhone(os) {
  this.os = os;
}

SmartPhone.prototype.isAndroid = function() {
  return this.os === 'Android';
};

SmartPhone.prototype.isIOS = function() {
  return this.os === 'iOS';
};
```

Now, we want to create an iPhone class, which should have `'iOS'` as it’s OS. It should also have the `faceIDScan` method.

First, we have to create an `Iphone` constructor function and inside it, we should call the `SmartPhone` constructor, like this:

```jsx
function Iphone() {
   SmartPhone.call(this, 'iOS');
}
```

This will set the `this.os` property to `'iOS'` in the `Iphone` constructor function.

The reason why we called `SmartPhone.call` method is because we need to change the value of `this` to refer to `Iphone`. It would be similar to calling the parent’s constructor in an object-oriented world.

The next thing is, we have to inherit methods from `SmartPhone` constructor. We can use our `Object.create` friend here, as follows:

```jsx
Iphone.prototype = Object.create(SmartPhone.prototype);
```

Now we can add methods for `Iphone`, using `.prototype` as follows:

```jsx
Iphone.prototype.faceIDScan = function() {};
```

Finally, we can create an object using `Iphone` as follows:

```jsx
let x = new Iphone();

// calling inherited method
console.log(x.isIOS()):
// true
```

## ES6 class

With the ES6, this whole ordeal is very simple. We can create classes (they are not the same as classes in C++ or other any class-based language, just a syntactical sugar on top of prototypical inheritance) and derive new classes from other classes.

Here is how we create a class in ES6:

```jsx
class SmartPhone {
  constructor(os) {
    this.os = os;
  }
  isAndroid() {
    return this.os === 'Android';
  }
  isIos() {
    return this.os === 'iOS';
  }
};
```

Now we can create a new class which is derived from `SmartPhone`, like this :

```jsx
class Iphone extends SmartPhone {
   constructor() {
     super.call('iOS');
   }
   faceIDScan() {}
}
```

Instead of calling `SmartPhone.call`, we are calling `super.call`. But internally, the JavaScript engine is doing this for us automatically.

Finally, we can create an object using `Iphone` as follows:

```jsx
let x = new Iphone();

x.faceIDScan();

// calling inherited method
console.log(x.isIos()):
// true
```

This ES6 example is the same as the previous constructor method example. But it’s much cleaner to read and understand.

## Conclusion

Let’s summarize what we have learned so far:

- In class-based languages, we can’t run the classes. We have to create objects from them in order to get anything done
- Inheritance in JavaScript isn’t the same as in class-based languages. Because there is no real concept of class. Objects inherit via a reference called as prototype
- `[[Prototype]]` is just a fancy way of referring to an object’s prototype. They’re both the same thing
- We can access an object’s prototype using either ` __proto__ ` property or `Object.getPrototypeOf` method
- We found out that the function’s prototype property acts as a blueprint for the object’s `[[Prototype]]` which is created using the `new` keyword
- We learned what happens when we access a property on an object and what role the prototype chain plays there
- Finally, we also learned about multiple ways of creating an object in JavaScript

I hope this blog post was useful. To learn more about inheritance in JavaScript take a look at the article on [MDN](https://developer.mozilla.org/en/docs/Web/JavaScript/Inheritance_and_the_prototype_chain).

* * * 
**Editor's note:** Seeing something wrong with this post? You can find the correct version [here](https://blog.logrocket.com/inheritance-with-javascript-prototypes/).

## Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps
 
![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)
 
[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
[Try it for free](https://logrocket.com/signup/).
* * *
The post [Inheritance with JavaScript prototypes](https://blog.logrocket.com/inheritance-with-javascript-prototypes/) appeared first on [LogRocket Blog](https://blog.logrocket.com).