Mastering Prototypal Inheritance in JavaScript: A Comprehensive Guide
Tags: javascript, oop, programming
Published: 2023-11-12 16:20:43

Understanding Prototypal inheritance in Javascript is the key concept to understand how objects really work in Javascript which has always been tricky when compared to other traditional OOPS patterns in different programming languages. Prototypal inheritance is a way in which our objects in JS can inherit properties/methods from other objects.

**This is one of the most commonly asked questions in Senior Frontend Interviews**

Let’s first go through a code snippet and understand it -

```js
//We have an object `person1` with two properties `name` and `place`
const person1 = {
  name: "bob",
  place: "Amsterdam"
}

// we have another object `person2` with property `name` 
const person2 = {
  name: "john"
}

console.log(person2.name) // john
console.log(person2.place) // undefined
```

The above code snippet is pretty clear about how we created two different objects while logging person2.place we get undefined which is correct and expected, let’s add something magical to the above code -

```js
person2.__proto__ = person1

console.log(person2.place) // Amsterdam
```

WHAT? Now we’re getting Amsterdam a value of `person2.place` that was never defined by us earlier. So, what’s going on here?

Let’s confirm if there’s any property place existing in person2 the object via `hasOwnProperty` method —

```js
console.log(person2.hasOwnProperty("place")) // false
```

So, what’s really going on here? We do not have any `place` property defined in the `person2` object but still, it’s returning a value when we’re trying to access it.

If you remember we wrote a magical line `person2.__proto__ = person1` and this is where everything happened, now let's understand how.

## Understanding Prototypal Inheritance in Javascript

In Javascript, all the objects have a hidden property `[[Prototype]]` which either stores `null` within it or stores references to another object, and then we’ve another method `__proto__` (proto property) which is a getter/setter of the hidden `[[Prototype]]` property of the object.

Whenever we try to fetch any property/method from any object, it has a default tendency to look over its own property, and if not found it checks within its [[Prototype]] property and returns the value. This is why we were able to get `place` property inside `person2` object which was originally defined inside `person1` object.

Let’s verify our concept and try to console `person2` —

![person2 has [[Prototype]] property](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9795h4nbo1farr068ghh.png)

We can clearly see in the above image that we’ve `[[Prototype]]` object inside `person2` which stores the reference of `person1` object created earlier.

## Prototype Chain
You might be wondering why is there another `[[Prototype]]` property inside the `[[Prototype]]` property of `person2` object. And first of all, what's this `[[Prototype]]` in the object that we never defined?

This is the concept of a prototype chain in which an object looks over its `[[Prototype]]` to fetch the property/method and if not found it iterates to the `[[Prototype]]` of its own `[[Prototype]]` and if again not found it goes on till it finds the null.

Isn’t it confusing, let’s understand by another example —

```js
let animal = {
  eats: true
};

let rabbit = {
  jumps: true,
  __proto__: animal
};

let kangaroo = {
  swims: true,
    __proto__: rabbit
}

console.log(kangaroo.eats) // true
```
![visualization of prototypal chaining
](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s65bszhxjyrxgg7bl1th.png)

This is how chained prototypal inheritance looks like when consoled out —


![prototypal chaining in picture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/36hlbk41l5rocaiz3nzc.png)

## Things to note about Prototypal Inheritance in object

1. The reference of the prototype can’t be like a loop, like creating a circle. Javascript will throw an error if we try to assign __proto__ in a circle.
2. The value of __proto__ can be either an object or null. Other types are ignored.
3. An object can only have a single [[Protype]] property within it, it never inherits from two objects at the same time.
4. Prototype chaining ends only when it encounters null, or else it’ll go to the n level of depth to the top finding the requested property in the object.
5. An object always looks first within itself to search for any property before looking to its [[Prototype]], if it gets the same property both within itself and [[Prototype]], it’ll give priority to its own property.

## Creating prototypal inheritance using Object.create()
We already saw a way in which we can inherit the property defined in any object to another object via the `__proto__` keyword. But we can do this in other ways too.

We can use `Object.create()` method to create any object and bind another object to its prototype. Let’s visualize how —

```js
let animal = {
  eats: true
};

let rabbit = Object.create(animal, {jumps: {value: true}})

console.log(rabbit.eats) // true
```

## Summary
In JavaScript, we have the ability to use properties defined in one object to be used by different objects, which is known as Prototypal Inheritance.

JavaScript looks for inherited properties in the prototype of the object, but also in the prototype of the prototype, and so on in the chain of prototypes.

This is one of the classic ways of using OOPS in javascript and it’s very useful when used effectively.

_Have any questions about prototypal inheritance? Let’s connect in a comment box!_