A Quick Introduction to JavaScript Prototypal Inheritance
Tags: javascript, programming
Published: 2022-08-04 12:55:00

---
author: Nazif Barassounon
date: '2022-08-04T13:30:00.000Z'
hero_image: /assets/blog/intro-to-proto/cover.jpeg
title: 'A Quick Introduction to JavaScript Prototypal Inheritance'
summary: "The prototypal inheritance is how, in JavaScript, we share reusable properties and methods throughout objects. In this article, we'll see how it works."
---

The prototypal inheritance is how, in JavaScript, we share reusable properties and methods throughout objects. In this article, we'll see how it works.

Say we represented a user with the following object:

```javascript
let user = {
  name: 'John Snow',

  getName() {
    return this.name;
  },
};
```

We want an admin user with the same shape and feature with an additional `isAdmin` property set to `true`. Here's how prototypal inheritance helps us achieve this without repeating ourselves:

```javascript
let user = {
  // ...
};

let admin = Object.create(user);
admin.isAdmin = true; // "isAdmin" is a new property set only in `admin`
admin.name = 'Daenerys Targaryen'; // "name" is an inherited property that is overwritten

console.log(admin.getName()); // Daenerys Targaryen ("getName" is also inherited from `user`)
```

By calling `Object.create(user)` we've made `user` the prototype of `admin`. It means that we have access to all the properties and methods of `user` through `admin`.

![Illustration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x1ihmwqqdjiz8zlssy2g.jpeg)

## The Prototype Chain

When we call `user.getName()` and `admin.geName()`, two different things happen:

- We find `getName` directly in `user`, but not in `admin`.
- For `admin`, we implicitly go one step further in its prototype (`user`) to find the elusive `getName`.

By going one step further to reach a prototype, we're walking through the prototype chain. This chain can expand if we introduce a root user, for example:

```javascript
let user = {
  //...
};

let admin = Object.create(user);
//...

let root = Object.create(admin);
root.isRoot = true;
root.name = 'Night King';

console.log(root.getName()); // Night King (inherited from `user`)
console.log(root.isAdmin); // true (inherited from `admin`)
console.log(root.isRoot); // true (proper to `root`)
```

Here, when we lookup `root.getName`, we walk through the prototype chain until the `user` prototype.

![Illustration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5n7uuxr6wbqkin4fax9v.jpg)

## The ES6 class

An ES6 class and its instances also use a prototype behind the scene. When we define a constructor, it stores all of its properties and methods in the `prototype` property. Let's define a `User` class and some instances to see that in action:

```javascript
class User {
  constructor(name) {
    this.name = name;
  }

  getName() {
    return this.name;
  }
}

const user1 = new User('Joe');
const user2 = new User('Kim');

console.log(User.prototype === user1.__proto__); // true
console.log(user1.__proto__ === user2.__proto__); // true
```

As you can see, the constructor and the instances all share the same prototype. We access the prototype using `prototype` in the constructor and `__proto__` in the instances.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i3dh4bxjro0f0u6pvil8.jpg)

## Wrap up

Sharing properties and methods between objects is important because it allows us to make our code reusable and well-organized. We achieve this in JavaScript through a concept called prototypal inheritance. A prototype is an object referenced by other objects seeking the same properties and methods. A prototype can also have a prototype which in turn has a prototype, and so on, forming the prototype chain. We walk through this chain when a property or method is not found directly in a given object.