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
Table of Contents
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.

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.
1 2 3 4 5 6 7 8 9 10 | var Person = function(firstName, lastName) { this.firstName=firstName this.lastName=lastName this.sayHi=function() { console.log(" Hello "+this.firstName+' '+this.lastName) } } |
We create two new objects (john & bill) from the Person function.
1 2 3 4 5 6 7 8 | var john = new Person("John","Dyer") john.sayHi(); //Hello John Dyer var bill= new Person("Bill","Gates") bill.sayHi(); //Hello Bill Gates |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | var Person = function (firstName, lastName) { this.firstName = firstName; this.lastName = lastName; }; Person.prototype.sayHi = function () { console.log(" Hello " + this.firstName + " " + this.lastName); }; var john = new Person("John","Dyer") console.log(john) john.sayHi(); var bill= new Person("Bill","Gates") console.log(bill) bill.sayHi(); |
The sayHi method no longer belongs to the john or bill objects.

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.
1 2 3 4 5 6 7 | console.log(john.__proto__ === Person.prototype) //true console.log(bill.__proto__ === Person.prototype) //true |
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.

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 Object | Corresponding Prototype |
|---|---|
| Object | Object.prototype |
| Array | Array.prototype |
| Function | Function.prototype |
| String | String.prototype |
| Number | Number.prototype |
| Date | Date.prototype |
| Boolean | Boolean.prototype |
| BigInt | BigInt.prototype |
| Symbol | Symbol.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
1 2 3 | console.log(Object.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.

The following example creates obj object using the Object constructor. It can access the hasOwnProperty because Object.prototype is its prototype
1 2 3 4 5 6 7 8 | obj = new Object(); obj.name="Roger Mayer" console.log(obj.hasOwnProperty("name")) //true |
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.
1 2 3 4 5 6 7 8 | obj2 = Object.create(null); obj2.name="Roger Mayer" console.log(obj2.hasOwnProperty("name")) //Uncaught TypeError: obj2.hasOwnProperty is not a function |
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

1 2 3 4 5 6 7 8 9 | var str = new String( "This is string" ); //str.__proto__ == String.prototype //str.__proto__.__proto__ == Object.prototype //str => String.prototype --> Object.prototype --> Null |
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.
1 2 3 4 5 6 7 8 | let primString="hi" let objString=new String("Hi") console.log(primString) console.log(objString) |
A console.log of both will make the difference clear.

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.
1 2 3 4 5 6 7 8 | console.log(primString.__proto__==objString.__proto__) //true //All methods of String.prototype still work on primitive strings. primString.slice(0,1) // |
Array.prototype
Similarly, Arrays inherit from Array.prototype
1 2 3 4 5 6 7 8 9 | var arr = ['Ford', 'Chevrolet', 'Buick', 'Tesla']; //arr.__proto__ == Array.prototype //arr.__proto__.__proto__ == Object.prototype //arr => Array.prototype --> Object.prototype --> Null |
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]]
1 2 3 4 5 6 | var person = { name: "Bill Gates"}; //prototype chain //person --> Object.prototype --> null |
Objects from constructor functions
We looked at this in the above examples.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | var Circle = function(radius) { this.radius=radius } Circle .prototype = { area: function () { return Math.PI * this.radius * this.radius; }, circumference : function() { return 2 * Math.PI * this.radius }, } var cir = new Circle (10) //cir.__proto__ == Circle .prototype //cir.__proto__.__proto__ == Object.prototype //cir => Circle.prototype --> Object.prototype --> Null |
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
1 2 3 4 5 | var obj1 = {a: 1}; // // obj1 ---> Object.prototype ---> null |
In the following example, we use Object.create to create obj2 using the obj1 as prototype.
1 2 3 4 5 | var obj2 = Object.create(obj1); // obj2 ---> obj1 ---> Object.prototype ---> null |
You can access the property of the obj1 from obj2 because it is its prototype.
1 2 3 4 5 | console.log(obj2.a); // 1 inheritated from obj1 |
You can create an object without a prototype by Passing the Null as the argument.
1 2 3 | Object.create(null). |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | var Person = function (firstName, lastName) { this.firstName = firstName; this.lastName = lastName; }; Person.prototype.sayHi = function () { console.log(" Hello " + this.firstName + " " + this.lastName); }; var john = new Person("John","Dyer") john.sayHi(); //Hello John Dyer var bill= new Person("Bill","Gates") bill.sayHi(); //Hello Bill Gates console.log("Change the method sayHi") //We change the sayHI method here //Return lastName+FirstName Person.prototype.sayHi = function () { console.log(" Hello " + this.lastName + " " + this.firstName); }; //Now both prints lastName+FirstName john.sayHi(); //Hello Dyer John bill.sayHi(); //Hello Gates Bill |
Writing doesn’t use prototype
The Prototype inheritance works only for reading the Properties. Write/delete operations work directly with the object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | var Person = function (firstName, lastName) { this.firstName = firstName; this.lastName = lastName; }; Person.prototype.sayBye="Bye"; var john = new Person("John","Dyer") var bill= new Person("Bill","Gates") console.log(john.sayBye); //Bye console.log(bill.sayBye); //Bye //Writing Property //This will create a new Property in the john object //does not change the Person.prototype.sayBye john.sayBye="Goodbye" console.log(john.sayBye); //Goodbye console.log(bill.sayBye); //Bye |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | var Person = function (firstName, lastName) { this.firstName = firstName; this.lastName = lastName; }; Person.prototype.sayBye="Bye"; var john = new Person("John","Dyer") var bill= new Person("Bill","Gates") console.log(john.sayBye); //Bye console.log(bill.sayBye); //Bye john.sayBye="Goodbye" console.log(john.sayBye); //Goodbye console.log(bill.sayBye); //Bye //Deletes sayBye from john delete john.sayBye console.log(john.sayBye); //Bye console.log(bill.sayBye); //Bye //sayBye already deleted. Hence does nothing delete john.sayBye console.log(john.sayBye); //Bye console.log(bill.sayBye); //Bye |
You can directly delete it from the Person.prototype. This will affect all the objects which have Person.prototype as their prototype
1 2 3 4 5 6 | delete Person.prototype.sayBye console.log(john.sayBye); //Undefined console.log(bill.sayBye); //Undefined |


