JavaScript Prototype — Understanding The Basics

Raj Maharjan
May 4, 2020 · 7 min read

The prototype is often associated with inheritance when comparing to Object-Oriented programming. But why? And what even prototype means in JavaScript. In this blog, I will explain what the prototype is and how it is designed and structured in JavaScript. And of course, the why part.

In JavaScript, all functions are objects, the only difference is that functions can be called.

// Here is a simple function
function Superman() {
// ...
}
// Since function Superman is also an object we can add properties and methods like in objects.
Superman.isHero = true;
Superman.test = function() {
console.log('test ok')
}
console.log(Superman.isHero) // true
console.log(Superman.test()) // test ok

In this blog, I am going to tell you a short story in which we have superheroes like Superman, Batman, and Wonderwoman each with their unique superpowers. And some scientists.

Superman: flight, superhuman strength, x-ray vision, heat vision, cold breath, super-speed, enhanced hearing, and high-invulnerability, etc.

Batman: gadgets, superhuman level strength, agility, intellect, etc.

Wonderwoman: superhuman strength and durability, flight, superhuman speed, reflexes, and agility; enhanced senses, including smell, vision, and hearing, etc.

Let’s slightly tweak the story where superpowers of each superhero are stored in a bag where they have access only to their own bag.

In JavaScript, we all have seen standard build-in objects like Array, Date, Object, Set, Promise, String, Number, etc. Let’s think of them as superheroes of JavaScript, and like in the story, their superpowers are also stored in a bag labeled ‘prototype’. Yes, that’s prototype, details to follow.

Image for post
Image for post

I am sure that we all have used superpowers in JavaScript quite a lot of times. Here they are:

Array: forEach, filter, sort, slice, concat, length, etc.

String: toUpperCase, toLowerCase, replace, substr, etc.

Set: has, add, delete, clear, values, etc.

Promise: then, catch, finally, etc.

All these properties (or methods) are stored in a property named ‘prototype’ of every function objects. That means a prototype is also an object. You can see all these properties (or methods) by accessing their prototype directly in the browser’s console — Array.prototype, Set.prototype, and so on. Below are some related images.

Image for post
Image for post
Image for post
Image for post

superheroes => function objects (Array, Set, Date, Promise, Map, etc.)

superpowers => properties and methods (length, forEach, map, size, etc.)

bag => prototype

Now introducing a group of scientists, who can create or clone these superheroes. Let’s call one of those scientists constructor who uses new operator to create instances of superheroes. Other scientists can be called Object.create, Object.setPrototypeOf, and syntax constructs. They have different approaches to prototyping.

// Lets first create our own Superhero in LAB1function Superhero(name, faction) {
this.name = name;
this.faction = faction;
this.XRayVision = false;
this.fly = false;
}
// add toggleXRayVision method to Superhero prototype
Superhero.prototype.toggleXRayVision = function() {
this.XRayVision = !this.XRayVision;
console.log(`Superhero ${this.name} has turned ${this.XRayVision ? "on" : "off"} X Ray vision.`);
};
// add toggleFlight method to Superhero prototype
Superhero.prototype.toggleFlight = function() {
this.fly = !this.fly;
console.log(`Superhero ${this.name} ${this.fly ? "is now flying" : "has stopped flying"} over ${this.faction}.`);
};
// create instances s1 & s2 using new operator
let s1 = new Superhero("Hero1", "Asia");
let s2 = new Superhero("Hero2", "Europe");
// **************s1.toggleXRayVision();
// Superhero Hero1 has turned on X Ray vision.
s2.toggleXRayVision();
// Superhero Hero2 has turned on X Ray vision.
// update method so that changes reflect in all instances
Superhero.prototype.toggleXRayVision = function() {
this.XRayVision = !this.XRayVision;
console.log(`Modified: Superhero ${this.name} has turned ${this.XRayVision ? "on" : "off"} X Ray vision.`);
};
s1.toggleXRayVision();
// Modified: Superhero Hero1 has turned off X Ray vision.
s2.toggleXRayVision();
// Modified: Superhero Hero2 has turned off X Ray vision.
// **************s1.toggleFlight(); // Superhero Hero1 is now flying over Asia.
s2.toggleFlight(); //Superhero Hero2 is now flying over Europe.
// this is called method shadowing or method overriding, affect only s1 instance but not prototype
s1.toggleFlight = function() {
this.fly = !this.fly;
console.log(`Defect: Superhero ${this.name} flying has been defected`);
};
s1.toggleFlight();
// Defect: Superhero Hero1 flying has been defected
s2.toggleFlight();
// Superhero Hero2 has stopped flying over Europe.
// dynamically update toggleFlight method for all instances
Superhero.prototype.toggleFlight = function() {
this.fly = !this.fly;
console.log(`Fly Repaired: Superhero ${this.name} ${this.fly ? "is now flying" : "has stopped flying"} over ${this.faction}.`);
};
// if s1 hadn't overridden this method, it would have been repaired too, so update on prototype level will not affect this method
s1.toggleFlight();
// Defect: Superhero Hero1 flying has been defected
s2.toggleFlight();
// Fly Repaired: Superhero Hero2 is now flying over Europe.

Note: For every new instance created, no new copy of prototype is created but all of them share (or are linked to) the same prototype.

How? Each instance (object) has a private property that holds a link to another object called its prototype (parent object). In most browsers, the private property is named __proto__ which is linked to the property prototype of a function object. You can find it in every object in JavaScript as shown in the below picture (__proto__ is at last).

Note: Standard notation for __proto__ is [[prototype]].

Image for post
Image for post
Image for post
Image for post

This concept of proto creates a prototype chain (explained below) where children have access to the prototype. This is how properties and methods are inherited in JavaScript.

However, if you replace or modify the __proto__ of any object, the chain might get broken which may cause the inheritance to not work properly. So updating it is not advisable unless it’s necessary and you know what you are doing.

// few expressions
let array = new Array(); // constructor
or, let array = []; // syntax constructs
array.__proto__ === Array.prototype // true
let set = new Set();
set.__proto__ === Set.prototype // true

Note: set inherits from Set.prototype not Set itself, which means property prototype literally is its prototype (parent object) and not Set.

In JavaScript, nearly all objects are instances of the Object.

// Array.prototype inherits from Object.prototypeArray.prototype.__proto__ === Object.prototype // truearray.__proto__.__proto__ === Object.prototype // trueObject.prototype.__proto__ // null
Image for post
Image for post

As shown in the above picture, you can see a chain of prototypes connecting all the way up to Object prototype object. This means Object sits at the top of the prototype chain whose __proto__ is null.

The interesting thing about the prototype chain is that when accessing a property, if a property is not found in an object, its __proto__ is looked through and if it is not found in __proto__ then __proto__ of __proto__ is looked through and it goes on until the end of the chain is reached i.e. null which finally returns undefined. And yes, console.log(array2[0]) from above picture prints 1.

So, for performance reasons, try to make the chain as small as possible. Also, you can use the hasOwnProperty method which every object inherits from Object.prototype to check if a property exists on the current object or not, and prevents traversing through the chain. Although it doesn’t check if the value of a property is undefined.

Lastly, we already know that initiating an object from a function inherits its prototype. However, we can also inherit from an object using Object.create method, which makes the first argument a prototype for new objects.

let obj = {a: 1, b: 2};
obj ---> Object.prototype ---> null
let o = Object.create(obj); // obj is prototype for o
o ---> obj --> Object.prototype ---> null
console.log(o.a) // 1
let arr = [1, 2];
arr ---> Array.prototype ---> Object.prototype ---> null
let a = Object.create(arr);
a --> arr --> Array.prototype ---> Object.prototype ---> null
console.log(a[1]) // 2

In general, prototype in JavaScript is an object (not necessarily stored in property prototype), to which new objects created from it are linked and thus can use its properties and methods.

In JavaScript, objects are king. If you understand objects, you understand JavaScript. — copied

If you want to learn more about prototype or prototype chain, here is the link: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

Thanks for reading. Comments are greatly appreciated. Please feel free to comment on how you think about this blog or have any questions.

Link to my previous blog: React Render Optimization Few Tips

A note from JavaScript In Plain English

We have launched three new publications! Show some love for our new publications by following them: AI in Plain English, UX in Plain English, Python in Plain English — thank you and keep learning!

We are also always interested in helping to promote quality content. If you have an article that you would like to submit to any of our publications, send us an email at submissions@plainenglish.io with your Medium username and we will get you added as a writer. Also let us know which publication/s you want to be added to.

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store