Dmitri Pavlutin
Thoughts on Frontend development

What Makes JavaScript JavaScript? Prototypal Inheritance

You don’t know JavaScript until you know prototypal inheritance. Prototypes greatly influence how objects work in JavaScript.

The prototypal inheritance is often asked during coding interviews since this knowledge is an indicator of how you know JavaScript.

This guide will help you easily understand prototypal inheritance in JavaScript.

1. Introduction

JavaScript has only primitives types, null, undefined and objects. A big world of objects. In JavaScript, contrary to languages like Java or PHP, there’s no concept of class that serves as a template to create objects.

An object is a composable structure and consists of multiple properties: key and value pairs.

For example, the following object cat contains 2 properties:

const cat = { sound: 'Meow!', legs: 4 };

Since I’d like to reuse legs property in other objects, let’s extract legs property into a specialized object pet:

const pet = { legs: 4 };
const cat = { sound: 'Meow!' };

That looks better.

But I still want to have legs property on cat. How can you connect cat with pet?

Inheritance can help you!

2. The prototype object

In JavaScript, an object can inherit properties of another object. The object from where the properties are inherited is named prototype.

Following the example, you can make pet a prototype of cat which will then inherit legs property.

When creating an object using the object literal, you can as well use the special property __proto__ to set the prototype of the created object.

Let’s use __proto__ and make pet the prototype of cat:

const pet = { legs: 4 };

const cat = { sound: 'Meow!', __proto__: pet };

cat.legs; // => 4

cat object now inherits legs from the prototype pet. Now you can use the property accessor cat.legs that evaluates to 4.

sound property, on the other side, is an own property because it’s defined directly on the object.

Inherited property from the prototype in JavaScript

The essence of prototypal inheritance in JavaScript: objects can inherit properties from other objects — the prototypes.

You’re probably wondering: why the need for inheritance in the first place?

Inheritance solves the problem of data and logic duplication. By inheriting, objects can share properties and methods.

For example, you could easily reuse legs property to create more pets:

const pet = { legs: 4 };

const cat = { sound: 'Meow!', __proto__: pet };
const dog = { sound: 'Bark!', __proto__: pet };
const pig = { sound: 'Grunt!', __proto__: pet };

cat.legs; // => 4
dog.legs; // => 4
pig.legs; // => 4

cat, dog, and pig all reuse the property legs.

Note: __proto__ is deprecated, but I’m using it for simplicity. In production code Object.create() is recommended.

2.1 Own vs inherited property

If an object has an own property and an inherited property with the same name, then JavaScript always picks the own property.

In the following example chicken object has an own property legs, but also inherits a property with the same name legs:

const pet = { legs: 4 };

const chicken = { sound: 'Cluck!', legs: 2, __proto__: pet };

chicken.legs; // => 2

chicken.legs evaluates to 2. JavaScript picks the own property legs (which is 2) over the inherited legs (which is 4).

Own vs inherited property in JavaScript

If you delete the own property, then JavaScript picks the inherited one!

const pet = { legs: 4 };

const chicken = { sound: 'Cluck!', legs: 2, __proto__: pet };

chicken.legs; // => 2
delete chicken.legs;
chicken.legs; // => 4

3. The implicit prototype

When you create an object, and no prototype is explicitly set, JavaScript assigns an implicit prototype specific to the type of object you’ve created.

Let’s look again at the pet object:

const pet = { legs: 4 };

pet.toString(); // => `[object Object]`

pet has just one property legs, however, you can invoke the method pet.toString(). Where did toString() come from?

When you’ve created the pet object, JavaScript has assigned to it an implicit prototype object. From this implicit prototype pet inherits toString() method:

const pet = { legs: 4 };

const petPrototype = Object.getPrototypeOf(pet);

pet.toString === petPrototype.toString; // => true

Object.getPrototypeOf(object) is an utility function that returns the prototype of an object.

4. The prototype chain

Let’s go deeper and create an object tail, making it also a prototype of pet:

const tail = { hasTail: true };

const pet = { legs: 4, __proto__: tail };

const cat = { sound: 'Meow!', __proto__: pet };

cat.hasTail; // => true

cat inherits the property legs from its direct prototype pet. But cat also inherits hasTail from the prototype of its prototype — tail!

Prototypes chain in JavaScript

When accessing a property myObject.myProp, JavaScript looks for myProp inside the own properties of myObject, then in the prototype of the object, then in the prototype’s prototype, and so on until it encounters null as the prototype.

In other words, JavaScript looks for inherited properties in the chain of prototypes.

5. But JavaScript has classes!

You may be confused regarding the statement that JavaScript has only objects. You’ve probably already used the class keyword in JavaScript!

For example, you can write a class Pet:

class Pet {
  legs = 4;

  constructor(sound) {
    this.sound = sound;
  }
}

const cat = new Pet('Moew!');

cat.legs;           // => 4
cat instanceof Pet; // => true

and create a cat when instantiating the class.

The secret is that class syntax in JavaScript is syntactic sugar on top of prototypal inheritance.

The above class-based code snippet is equivalent to the following:

const pet = {
  legs: 4
};

function CreatePet(sound) {
  return { sound, __proto__: pet };
}
CreatePet.prototype = pet;

const cat = CreatePet('Moew!');

cat.legs;                 // => 4
cat instanceof CreatePet; // => true

CreatePet.prototype = pet assignment is necessary to make cat instanceof CreatePet evaluate to true.

When working with class-es you can completely forget about prototypes.

6. Summary

In JavaScript, objects inherit properties from other objects — the prototypes. That’s the idea of 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.

While prototypal inheritance seems clumsy at first, when understanding it you could enjoy its simplicity and possibilities. Objects inherit properties from objects — what could be simpler?

Have questions about prototypal inheritance? Ask in a comment below!

Like the post? Please share!

Quality posts into your inbox

I regularly publish posts containing:

  • Important JavaScript concepts explained in simple words
  • Overview of new JavaScript features
  • How to use TypeScript and typing
  • Software design and good coding practices

Subscribe to my newsletter to get them right into your inbox.

Join 2005 other subscribers.

About Dmitri Pavlutin

Software developer, tech writer and coach. My daily routine consists of (but not limited to) drinking coffee, coding, writing, coaching, overcoming boredom 😉.