Note: This post is work-in-progress learning-note and still in active development and updated regularly.
In previous learning-note post, JavaScripts Objects – The Basic some basic features of objects: syntax, creating objects with literals, properties & methods, assessing object properties & methods were discussed.In this learning-note post, more advanced features of creating new objects with constructor function, the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Using_the_Object\.create_method" target="_blank" rel="noopener">object.create</a> method , object inheritance & prototype will be discussed.
Object Prototypes
On MDN prototype & prototype chain is describes as :
JavaScript is a prototype-based language. Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. By definition, null has no prototype, and acts as the final link in this prototype chain.
All objects are created as instances of object and it properties (and methods) are are linked to object.prototype.
Prototype
In JavaScripts Objects – The Basics, we discussed basic object syntax, properties & methods, creating new objects, and modifying properties. In this learning-note post, we will learn about object prototypes, inheritance to extend object. On MDN, object prototypes are referred as “the mechanism by which JavaScript objects inherit features from one another“.
Lets examine in the the following empty Car object example which is defined using a constructor function.
//initialize an object Car
let Car = new Object();
//check prototype of Car object
Object.getPrototypeOf(Car);
//OUTPUT
{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, __lookupGetter__: ƒ, …}
//check prototype with __proto__
Car.__proto__;
//OUTPUT
{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, __lookupGetter__: ƒ, …}
In the example above an empty Car object without any properties was created using object constructor function. When we check prototype of this newly created object with Object.getPrototypeOf() method (line 5), the new Car object instance inherits in properties and methods from Object.prototype (line 7). All objects in JS are descended from Object constructor and all objects inherit in properties and methods from Object.prototype.
Object [[Prototype]] can also be found using the __proto__ property (line 10). __proto__ is a property that exposes the internal [[Prototype]] of an object. In the output (line 12) we get the same results as obtained with Object.getPrototypeOf().
NOTE: It is important to understand that there is a distinction between an object’s prototype available via <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf">Object.getPrototypeOf(obj)</a>, or via the deprecated <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">__proto__</a> property) and the prototype property on constructor functions. The former is the property on each instance, and the latter is the property on the constructor. [Source: MDN]
Prototype Chain
Lets define the Car object by adding some property parameters as follows:

In the example above, three property parameters (make, model and year) were assigned to our Car object (line 2) which become available to inherit to other object instances, in addition to build-in properties and methods from object.prototype (Figure ).
Tip: All objects in JavaScript are descended from Object; all objects inheri properties and methods from Object.prototype, although they may be overridden. – MDN
List of properties defined for the new myCar object instance (via Car() constructor) make, model and year as well as other properties & methods (eg. valueOf, isPrototypeOf, watch etc) defined for Car‘s prototype object , which is <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" target="_blank" rel="noopener">object</a> are shown Figure (right panel). The list also confirms that the prototype chain (shown below) is working.

To demonstrate whether methods that are NOT defined in myCar object instance (i.e. valueOf(), ..) are available we tested myCar.valueOf() in line 12 and its out put is shown in line 14. Quoting its explanation from MDN below:
- The browser initially checks to see if the
myCarobject has avalueOf()method available on it. - It doesn’t, so the browser then checks to see if the
myCarobject’s prototype object (Car()constructor’s prototype) has avalueOf()method available on it. - It doesn’t either, so the browser then checks to see if the
Car()constructor’s prototype object’s prototype object (Object() constructor‘s prototype) has avalueOf()method available on it. It does, so it is called and displayed in output (line 14).
Where Inherited Properties are Defined?
On MDN object reference page, a long lists of properties and methods are listed but not all are inherited to new object instances created from the constructor. The prototype properties that begin with Object.prototype., are inherited but not that begin with Object. For example, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch">Object.prototype.watch()</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">Object.prototype.valueOf()</a>, etc., are inherited where as <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is">Object.is()</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a> are not not inherited. Properties and methods starting with with Object. are available for Object() constructor only.
In addition, there is a long list of standard built-in objects (or objects in global scope) properties and methods defined on prototype of objects with global scope (eg., like <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number">Number</a>, and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a>).
Prototypal Inheritance
In JS an object is referred as prototypical object, which acts as a template object its properties can be used to create new objects. Additionally, any object can be linked as the prototype for other objects thus making possible to inherit the properties from initial objects to other linked objects below in the prototype chain.
JS object properties and methods can be shared through template objects that have the ability to be cloned and extended. This is known as prototypical inheritance.

In the example above (modified from The Modern JavaScript Tutorial) shown in Fig , a car object with a Toyota property and a value of 'Red' is initialized (lines 2-3). Similarly, a truck object with Ford property and a value of 'Black' is initialized (lines 5-6).
Now, lets say we want to access car object property from truck object, we can set car object as prototype of truck object using __proto__ keyword (line 9). When we console.log to access truck.toyota (Toyota is not a property of truck) it uses [[prototype]] link to find it from car and it outputs Red, property value from car object (line 12). In the example, car object is prototype of truck and truck prototypally inherits from car object.
Inheritance with Prototype Chain
Inheriting Properties
To quote from MDN Documentation JS objects are “dynamic “bags” of properties (referred to as own properties)“. As we know from our previous example that objects are linked to a prototype object through its prototypal chain until its property is found or it reaches end of the prototype chain (null).
//create Car function with two properties
let Car = function () {
this.make = 'Toyota';
this.year = 2017;
}
// create myCar object from Car function
let myCar = new Car();
//access myCar property
console.log(Car); // OUTPUT => {make: "Toyota", year: 2017}
//Access myCar prototype
myCar.__proto__; // OUTPUT => {constructor: ƒ}
//add properties in Car function's prototype
Car.prototype.year = 2018;
Car.prototype.model = "Corolla";
//Check property on myCar object
console.log(myCar.make); //OUTPUT =>Toyota
console.log(myCar.year); //OUTPUT =>2018
console.log(myCar.model); //OUTPUT =>Corolla
console.log(myCar.engine); //OUTPUT =>undefined
In the example above, we initialized Car constructor function with two properties make and year (lines 2-5). Then we created an object myCar from function Car() in line 7. This new object myCar inherits make and year properties from Car() function (line 9). If we accessed its prototype with __proto__ construct (line 11), it shows it inherits from constructor Car() function.
Now lets add two properties to Car() function prototype. In line 14, we change year to 2018 and in line 15, we add a new property model as "corolla“. Lets check myCar object instance prototype chain:
//Access prototype chain
myCar.__proto__; // OUTPUT => {year: 2018, model: "Corolla", constructor: ƒ}
myCar.__proto__.__proto__; // OUTPUT=> object {..}
myCar.__proto__.__proto__.__proto__; //OUTPUT => null
This our Car() constructor function’s full prototype chain looks like –
{make:"Toyota", year:2017} —> {year:2018, model:"Corolla"} —> Object.prototype —> null
Finally, lets check property inheritance of myCar object instance (lines 18-20). Explanation what is going on there (modified from MDN Documentation):
Line 18: It checks whether ‘make’ has its own property on myCar and find its value "Toyota" and displayed.
Line 19: It checks whether ‘year’ has own property on myCar object and find its value is 2018. But the prototype also has a ‘year’ property, but it’s not visited. This is called “property shadowing.”
Line 20: It checks whether a 'model' own property on myCar and it is No. Then it checks its prototype. Is there a 'model' own property on myCar.[[Prototype]]? Yes, its value is "Corolla".
Line 21: Is there a 'engine' own property on myCar? No, check its prototype. Is there a ‘engine’ own property on myCar.[[Prototype]]? No, check its prototype. myCar.[[Prototype]].[[Prototype]] is null, stop searching, no property found, return undefined.
Note: Every object descended from Object inherits the hasOwnProperty method. This method can be used to determine whether an object has the specified property as a direct property of that object.
Inheriting Methods
In JS methods, in the form of a function, can be added to an object as a property. The function ( method) acts similar to any other object property and inherited to other object instance.
//initialize Car object
let Car = {
make: 'Toyota',
reminder: function() {
return `Bring your ${this.make} for oil change`;
}
};
//access reminder method
console.log(Car.reminder());
//OUTPUT => Bring your Toyota for oil change
//Create myCar Object from Car object
let myCar = Object.create(Car);
//add property to myCar Object
myCar.make= 'Ford'; //=> Ford
//Check property in myCar object
console.log(myCar.make); // OUTPUT=>Ford
console.log(myCar.reminder());
//OUTPUT => Bring your Ford for oil change
In the above modified example from MDN Documentation, we initialized Car object with one property make and one reminder() method (lines 2-7). In line 5, this refers to Car object. When reminder() method was accessed (line 9), it outputs expected reminder message string in console (line 10).
A new myCar object instance was created from Car object using object.create() method (line 13). The myCar object (line 13) inherits its properties & methods from Car Object (line 4). In line 15, a new property value "Ford" was assigned to make property on myCar object.
When value of reminder() method on myCar object was accessed (line 19), its console output was inherited from reminder() method from Car object (line 5) with value of this referring to myCar object (line 21).
Note: Some clarification on the value of <strong>this</strong> here. When reminder() for Car object was accessed (line 9) this refers to Car object. In the reminder() method on myCar object this refers to myCar object (line 13).
Creating New Objects
Lets revisit creating new objects (as described in MDN Documentation) with different (object, array, function) syntax construct.
With Syntax Constructs
In the following example from MDN Documentation, we create a car object using object, array & function syntax.
//initialize with object syntax
let car = {make: 'Toyota', year: 2018};
//access car object
console.log(car); // OUTPUT => {make: "Toyota", year: 2018} //object
//initialize with Array syntax
let car = ['Toyota', 'Honda', 'BMW'];
//access car object
console.log(car); //OUTPUT => (3) ["Toyota", "Honda", "BMW"] //Array
//initialize with Function syntax
function car() {
return 'Ford is a popular passenger car.';
}
//access car() function
car(); //OUTPUT => "Ford is a popular passenger car."
In the example, car object was initialized using object syntax (line 2). To quote its explanation from MDN: the object car has Object.prototype as its [[Prototype]] and car has no own property named ‘hasOwnProperty‘ (hasOwnProperty is an own property of Object.prototype). So car inherits hasOwnProperty from Object.prototype. Object.prototype has null as its prototype. Its prototypical is: car —> Object.prototype —> null
Next using array syntax, car object with three parameters was created (line 7). To quote its explanation from MDN: the arrays inherit from Array.prototype (which has methods indexOf, forEach, etc.). The prototype chain looks like: car —> Array.prototype —> Object.prototype —> null .
Finally, the same car object was initialized using function syntax (lines 12-14) with a string as its return value (line 13). Quoting its explanation from MDN: functions inherit from Function.prototype (which has methods call, bind, etc.). Its prototype chain looks like this: car —> Function.prototype —> Object.prototype —> null .
With a Constructor Function
In JS a constructor is a function and objects will have a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor#Description" target="_blank" rel="noopener">constructor</a> property. Such constructor functions are also referred as new operators. To quote from MDN Documentation “The new operator creates an instance of a user-defined object type or of one of the built-in object types that has a constructor function“.
//Initialize constructor function
function Graph() {
this.vertices = [];
this.edges = [];
}
// initialize Graph.prototype
Graph.prototype = {
addVertex: function(v) {
this.vertices.push(v);
}
};
// initialize g object instance on Graph()
let g = new Graph();
//Access g object properities
console.log(g);
//OUTPUT => Graph {vertices: Array(0), edges: Array(0)}
In the example above, g is an object with own properties 'vertices' and 'edges'. g.[[Prototype]] is the value of Graph.prototype when new Graph() is executed.
With object.create() Method
Objects can be created using ES6 introduced object.create() method as shown below (explanation based on MDN Documentation):
//initialize vehicle object
let vehicle = {color : 'Red'};
// vehicle ---> Object.prototype ---> null
//assign car object instance from vehicle
let car = Object.create(vehicle);
//Prototypcal chain => car ---> vehicle ---> Object.prototype ---> null
console.log(car.color); // => Red (inherited)
//assign truck object instance from car object prototype
let truck = Object.create(car);
//Prototypal chain => truck --> car --> vehicle --> Object.prototype --> null
console.log(truck.color); // => Red (inherited)
//assign motorBike object instance with object (null)
let motorBike = Object.create(null);
//prototypal chain => motorBike ---> null
console.log(motorBike.hasOwnProperty);
// undefined, because d doesn't inherit from Object.prototype
Modifying Object Prototypes
Object prototypes can be modified by adding new properties (or methods) to an existing object or object constructor. We have added or created new properties in earlier examples too. Here we will add some properties & methods.
Adding Prototype Properties
In the following example, a Car object was initialized using constructor function (lines 2-4) with a single make property and 'Toyota' as its value. Object initialization was confirmed from console.log output of Car() (line 6).
//initialize Car object
let Car = function () {
this.make = 'Toyota'
}
//Access car();
console.log(Car); // OUTPUT => { this.make = 'Toyota'}
//create new myCar object instance
let myCar = new Car();
//add two properties to Car prototype
Car.prototype.year = 2018;
Car.prototype.model = "Corolla";
//Access myCar properties
console.log(myCar.make); // OUTPUT => Toyota
console.log(myCar.year); // OUTPUT => 2018
console.log(myCar.model); // OUTPUT => Corolla
To add new properties to myCar object instance was created on Car object prototype (line 9). In line 12-13, two new properties year and model with 2018 and 'Corolla' values respectively in Car.prototype._ . When myCar properties for make, year & model were accessed in console.log their outputs (line 16-18) confirmed that two new properties (line 12-13) were successfully added on Car prototype.
Adding/Modifying Prototype Methods
Prototype property of a constructor function can be modified (i.e. methods can be added or modified). Lets revisit our earlier Car() constructor function shown below:
//define Car function with two properties
function Car(name, year) {
this.make = name;
this.year = year;
}
//create new myCar instance
let myCar = new Car('Toyota', 2018);
// access myCar has Property
console.log(myCar); //OUTPUT => Car {make: "Toyota", year: 2018}
//proof : myCar is constructor function
Object.getPrototypeOf(myCar); // OUTPUT => {constructor: ƒ}
// Add reminder method to the Car prototype
Car.prototype.reminder = function () {
return `Bring your ${this.make} for oil change`;
}
//Access on console
myCar.reminder(); // OUTPUT => "Bring your Toyota for oil change"
// modify reminder method to the Car prototype
Car.prototype.reminder = function () {
return `Bring your ${this.make} ${this.year} for oil change`;
}
// access modified reminder() method
myCar.reminder(); // OUTPUT => "Bring your Toyota 2018 for oil change"
In the example above, Car() constructor function was defined with two parameters (lines 2-5). Then myCar instance from Car object with 'Toyota" and 2018 as arguments was created (line 8). The myCar object instance inherits make and year property from Car prototype (line 11) and its a constructor function (line 14).
A reminder() method with a return message was added to the Car prototype (line 17-19). Here this keyword refers Car object. The reminder() method was successfully added to Car prototype and is inherited to its myCar instance (line 21). The reminder() method was modified by adding year variable from Car object as ${this.year}, where this refers to Car prototype. The reminder() method was successfully modified as shown in line 28.
Wrapping Up
Prototype and its inheritance is often considered confusing to even experienced JS developers. In this earning-note post we covered object prototypes, prototype chain, prototype inheritance, including creating new objects with prototypes and modifying prototypes. In the next learning-note we’ll look into JS classes – creating new objects with prototypes, extending classes and use of extends, super and mix-ins.
Related: Deep Dive into JavaScript Property Descriptors
Useful Resources & Links
While preparing this post, I have referred the following references extensively. Visit original link for more detailed information.
- JavaScript prototypes. It doesn’t have to be complicated | SiMedia Tech
- Gentle explanation of ‘this’ keyword in JavaScript – by Dmitri Pavlutin | dmitripavlutin.com
- Revealing the Inner Workings of JavaScript’s “this” Keyword – by Ivaylo Gerchev | Site Point
- “this” in methods | The Modern JavaScript Tutorial
- Chapter 5: Prototypes | You Don’t Know JS: this & Object Prototypes – by Kyle Simpson
- Prototypal Object-Oriented Programming using JavaScript – by Mehdi Maujood | A List Apart
