DEV Community

Rishav Pandey
Rishav Pandey

Posted on • Originally published at thenomadtechie.Medium

Mastering Prototypal Inheritance in JavaScript: A Comprehensive Guide

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 -

//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
Enter fullscreen mode Exit fullscreen mode

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 -

person2.__proto__ = person1

console.log(person2.place) // Amsterdam
Enter fullscreen mode Exit fullscreen mode

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 —

console.log(person2.hasOwnProperty("place")) // false
Enter fullscreen mode Exit fullscreen mode

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

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 —

let animal = {
  eats: true
};

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

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

console.log(kangaroo.eats) // true
Enter fullscreen mode Exit fullscreen mode

visualization of prototypal chaining<br>

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

prototypal chaining in picture

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 —

let animal = {
  eats: true
};

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

console.log(rabbit.eats) // true
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (0)