Prototype Inheritance in JavaScript

The Javascript uses the Prototypes to implement the inheritance. In this tutorial, we will learn how to use Prototype to create Inheritance. Inheritance makes code reusable, readable & maintainable by sharing the instance of existing properties & methods across objects

What is Prototype Inheritance

Inheritance is a mechanism by which one object acquires the property and behavior of another object. In classical languages like C# & Java, this is done with classes.

But in Javascript, we do not have the concept of classes. JavasScript has only Objects. To implement inheritance JavaScript makes use of Prototype. The Inheritance is known as Prototype Inheritance.

Prototype Recap

A Prototype is just another JavaScript Object. The JavaScript assigns it to the [[Prototype]] property of the object when it creates it. The [[Prototype]] is the internal property and is hidden from us. This Property points to the Prototype Object or NULL.

Accessing the Prototype of an object

We cannot access the [[Prototype]] directly. But we can access it either by using the __proto__ property or using the getPrototypeOf method of the Object

The Prototype Chain

Prototype objects are just like any other Javascript object. Hence Even they also have prototype objects. We can traverse using an object’s prototype until we find null. This is referred to as prototype chain

The image below shows a Prototype chain in JavaScript.

At the bottom, we have John object, which has a [[Prototype]] property. It points to Foo object. The Foo object is the prototype of the John object.

The Prototype object can also have a Prototype Object. Boo is a Prototype of Foo. The Prototype chain usually ends with Object.prototype. The Prototype of Object.prototype is NULL.

Prototype inheritance in JavaScript

Need for Inheritance

First, let us understand why we need Inheritance in the first place.

Take a look at the following snippet. The constructor function Person defines two properties and one method sayHi.

We create two new objects (john & bill) from the Person function.

The code above works perfectly well. But we can make it better

The issue is with the sayHi method. Every time we create a new Person it also creates an instance of sayHi method in the Memory.

If you happen to create many such Person objects, then it will also mean that you have many instances of sayHi occupying the memory.

The solution is to create a single instance of sayHi method and share it among all the objects created from the Person function.

This is where we make use of Prototype Inheritance.

Prototype Inheritance

Whenever we create a function, JavaScript adds an extra property prototype to the function. The prototype property is an object. We can refer to it using the <functionName>.prototype. In the case of Person function, it becomes Person.prototype.

Whenever we create a new object using a new operator from the Person Function, the Person.prototype becomes the Prototype of the newly created object.

In the code from the previous example, we make a small change. We remove the sayHi function from the Person function. We add it to the Person.prototype object.

Run the code, and you will see the same result as the previous one.

The sayHi method no longer belongs to the john or bill objects.

JavaScript inheritance example

But you will find them in the __proto__ property of both john & bill objects. Both these methods actually point to the Person.prototype object. You can use the === to check if they are equal.

We have only one instance of Person.prototype object in the memory. The prototype Property of the function point to it. The [[Prototype]] property of the john & bill objects also point to it.

But how did john.sayHi() & bill.sayHi() work if they did not contain the sayHi method.

How Prototype Inheritance Works

When we ask for a property or method from an object, JavaScript tries to read the property from the object itself. If the object lacks the property, then JavaScript looks for the property in the prototype object. And if that prototype object also does not contain the property, then JavaScript looks in its prototype. This process continues until it reaches the Object.prototype. The prototype of Object.prototype is NULL. Hence the search stops there and returns the undefined value.

When we call john.sayHi(), The javascript searches for sayHi method in the john object. It does not find it there. So it looks for it in the __proto__ of john. The __proto__ of john points to Person.prototype. It finds the method there, hence executes it, and returns the result.

Javascript Prototype Inheritance

Inheritance & Built-in Objects

JavaScript has several built-in or native Objects. The following tables show the list of built-in objects, with their corresponding prototypes.

Built in ObjectCorresponding Prototype
ObjectObject.prototype
ArrayArray.prototype
FunctionFunction.prototype
StringString.prototype
NumberNumber.prototype
DateDate.prototype
BooleanBoolean.prototype
BigIntBigInt.prototype
SymbolSymbol.prototype

Object.prototype

The Object() is a built-in constructor function. We can create new objects using it. All the objects that we create from it get the Object.prototype as their prototype

As you can see from the image, the Object.prototype defines few methods. The constructor property points to Object() Constructor function. Because Object.prototype is created from it.

There are properties like hasOwnProperty, IsPrototypeOf, propertyIsEnumerable, toLocalString, toString, valueOf, etc. Every object that inherits from the Object.prototype have access to these properties.

properties that you inherit from Object.prototype

The following example creates obj object using the Object constructor. It can access the hasOwnProperty because Object.prototype is its prototype

You can verify it by creating the new object with null as its prototype as shown in the example below. Accessing the hasOwnProperty results in TypeError, becuase it is not present in its prototype chain.

String.prototype

Similarly, when you create a new String object, the newly created objects will get String.prototype as their prototypes.

As you can see from the image, the String.prototype has many methods. Due to Prototype Inheritance, the newly created objects will have access to all these methods.

The prototype of String.prototype is Object.prototype. Hence the newly created object can also access the methods of Object.prototype

properties that you inherit from String.prototype

Simple primitive types

Note that JavaScript has seven simple primitive types. They are string, boolean, number, BigInt, Symbol, null, and undefined. They are not objects.

But JavaScript creates an object wrapper around the primitive types. This enables us to use prototype methods of the String object on the primitive string.

A console.log of both will make the difference clear.

Primitive String Vs Object String

But comparing the __proto__ of both results in true. You can also access all the methods of the String.prototype. When we call a property or method on a string primitive, JavaScript automatically coerces it to a String object. Hence it works.

Array.prototype

Similarly, Arrays inherit from Array.prototype

Creating objects with Prototype

Apart from the Object constructor function, there are other ways in which you can create an Object.

Objects Created with Literal Syntax

The following example creates person object using the object literal syntax. The objects created using the literal syntax gets the Object.prototype as its [[Prototype]]

Objects from constructor functions

We looked at this in the above examples.

With Object.create

Using Object.create method allows us to specify the prototype of the newly created object.

For Example, let us create an object obj1 using the literal syntax

In the following example, we use Object.create to create obj2 using the obj1 as prototype.

You can access the property of the obj1 from obj2 because it is its prototype.

You can create an object without a prototype by Passing the Null as the argument.

Adding Property to Prototype

We can add or alter the Property or method of a Prototype object. These changes will immediately become visible in all of the objects that are based on that prototype

In the example below, we change the sayHi method midway through the program.

Writing doesn’t use prototype

The Prototype inheritance works only for reading the Properties. Write/delete operations work directly with the object.

Delete also do not use prototype

Similarly, the delete operator deletes the property from the object. But it will not traverse the prototype chain to delete the objects from the prototype

In the example, we delete the sayBye from john. A similar property exists in Person.prototype. It will not affect it.

You can directly delete it from the Person.prototype. This will affect all the objects which have Person.prototype as their prototype

Leave a Comment

Your email address will not be published.

Scroll to Top