Prototype in JavaScript – What, How and Why?

Prototype in JavaScript is one of the most vital topic that every JavaScript develper should be aware of.

if you’re someone who’s new to JavaScript, you might have been always intimated by the concept of prototype in JavaScript because you think that it’s quite complicated.

No worries if that’s your case since in this blog post we’ll try to simplify this topic for you that you can make good friends with prototype in JavaScript and write better JavaScript code that will make sense in the future.

To begin, let’s start by the most obvious question…

What is prototype in JavaScript?

To explain this concept, I had to pick the following quote from the MDN documentation,

Prototypes are the mechanism by which JavaScript objects inherit features from one another.

Source here…

In other words, prototypes are the tool that allow you to use inheritance in JavaScript. In fact, in contrast of many other class-based programming languages such as Java and C++, JavaScript is a prototype-based language.

So, basically in JavaScript, objects have a prototype object that can be considered as blueprint object which properties and methods are inherited from.

In the same way, an object’s prototype object might have a prototype object, which it inherits methods and properties from…You see? In this way, we’re building a sort of a chain…This is what we usually refer to in JavaScript as a prototype chain. Indeed, it explains why, for instance, the .valueOf() method of an Object object is available to an Array object.

Does it make sense? Not yet? Let’s answer the following question to make a bit clearer…

How does prototype in JavaScript work?

In order that you can follow through easily to understand the concept of prototype in JavaScript, and in order to make it a little bit quite realistic, We’d like to provide you with the following scenario which we’re going to pseudo-replicate in JavaScript.

The scenario…

Let’s assume that we want to track the people that visit our site to provide them with the best user experience ever. So , we have decided to give them the ability to save custom preferences for their next visits to our site.

So, first of all, we’re going to define a constructor function Visitor that is going to represent our site’s visitors.

function Visitor(ip, country, device, agent){
  
  // properties
  this.ip = ip;
  this.country = country;	
  this.device = device;
  this.agent = agent;
  
  //methods
  // will be fired whenever a visitor wants to perform this action...
  this.saveMyCustomPreferences =  function(){
  	console.log('Saved...');
  }
  
}

Then, let’s assume that one day two visitors landed on our site for some reason…

So, the next logical instruction would be to create a Visitor instance for each one of them,

const visitor1 = new Visitor('0.0.0.0','Algeria','mobile','Chrome Agent');
const visitor2 = new Visitor('0.0.0.0','USA','tablet','Mozilla Agent');

Now, what I want you to do is to open your dev tools on your browser and copy/past the two above pieces of code on your JavaScript console one after the other and hit Enter.

The exploration…

If you’re ready, let’s make some fun tests and explore things…

//Test 01:
console.log(visitor1.country);
visitor1.saveMyCustomPreferences();

//Test 02:
visitor1.valueOf();

//Test 03:
console.dir(visitor1);

//Test 04:
console.dir(Visitor);

Test 01

If you try the first test on your console, you should be having the visitors1’s country displayed and the string “Saved…” printed out which makes senses as they have been defined on the Visitor constructor function above.

Test 02

For the second test, you’ll get the primitive value of visitor1 object printed out to the console…But, hold on! We’ve never defined valueOf() method in our Visitor constructor! So, what’s going on? Let’s see the third test to understand what’s happening….

Test 03

If you try the third test, you should get something like that,

if you watch closely, you will notice that the visitor1 instance object has got a __proto__ property that refers to the Visitor prototype object [the object highlighted with the red box]. So, whenever a new instance is created, a prototype object is bound to it which contains ,by default, a constructor function (as shown in the image above).

In the same way, the Visitor prototype object’s prototype object refers to the Object prototype object [the object highlighted with the blue box]. Therefore, the method valueOf() is being accessible through visitor1 instance as in the test number 3 since it was found by walking up the chain of prototypes.

Additionally, whenever a new Visitor instance object is being created, its __proto__ proprety is going to refer to the same Visitor prototype object that visitor1 instance __proto__ proprety is linked to. So, what should you understand is that there’s only one protoype object of type X that all instances of object of type X refer to.

Want a proof?

Let’s make the following check,

console.log(visitor1.__proto__ === visitor2.__proto__); // output: true

The above strict comparison returns true which means that we are talking about exactly the same object that __proto__ in visitor1 and visitor2 refers to.

N.B, accessing the prototype object through .__proto__ is deprecated. Use Object.getPrototypeOf(obj) instead. However, for the sake of simplicity and ease of access, we’re going to use .__proto__ in this tutorial no matter.

Test 04

In the fourth and last test, i wanted to emphasis something important when it comes to prototype in JavaScript, but first if you try it on your JavaScript console, you should see something like the following being printed out,

Notice that the Visitor constructor function has got a .__proto__ property and .prototype property. These two properties are different. So, you should make the clear distinction between them since .__proto__ in the constructor refers to its own prototype which is in this case a function prototype object ( Remembre! functions in JavaScript are just ordinary objects). Therefore, something like that Visitor.apply(), Visitor.bind() is doable. On the other hand, .prototype representes a template for instances of type Visitor.

The flow…

That’s it…I hope that we’ve made it clear till now? Nevertheless, I want to end this section by sharing with you the following schema which illustrates our last example in boxes are rows. Maybe, this would help making things even clearer and easier

Following this diagram, you can make some other tests for the sake of trying things out and understanding the flow of prototype in JavaScript.

We have so far understood what are prototypes and how to use them in JavaScript. However, we’re missing on the most important question which is…

Why prototype in JavaScript?

Let’s first give you a straight forward answer, then we’ll discuss it together…

So…Using prototype in JavaScript might make your code run faster and use less memory.

Back to our last example…Let’s assume again that for some crazy reasons we’ve had like 1 million visitors at a given moment!

For those 1 million visitors our code will be creating 1 million instances of Visitor. Notice, that in this 1 million instances the method .saveMyCustomPreferences() remains the same for all of them. Right? Isn’t it like a waste of time? Could we make it better?

So, what if we take advantage of the Visitor prototype to make things quite bit faster knowing, remembre, that there’s only one instance of Visitor prototype that all Visitor instances will refer to.

If we tweak our last example in this way,

function Visitor(ip, country, device, agent){
  
    // properties
    this.ip = ip;
    this.country = country;	
    this.device = device;
    this.agent = agent;

    // methods
  
}

// define the method directly in the prototype object
Visitor.prototype.saveMyCustomPreferences =  function(){
  	console.log('Saved...');
}

Now, the saveMyCustomPreferences() method lives in the Visitor prototype objet and is being created only once.

Making this simple change to our code would make our code run faster

Similarly, when it comes to memory usage, keeping an unchanged method for all instances of an object in the constructor function of that object wouldn’t be a wise decision. Especially, if your code is going to create a huge number of instances of that type of object. So, the memory usage would grow significatly which might decrease the performance of your code.

Taking advantage of the concept of prototype in JavaScript can be beneficial in terms of usage of resources and performace of your code.

So yeah…That’s it! I hope that I’ve helped you have a better understanding of prototype in JavaScript, and this is going to help you reconsider using prototypes the right way in your future JavaScript projects.

If you have any question, please use the comment section below.

And by the way, if understanding the internal working of JavaScript still interests you. I have got a good read for you here. It’s about how JavaScript works behind the scenes.

Enjoy 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *