What on Earth are JavaScript Prototypes?

What on Earth are JavaScript Prototypes?

The often-overlooked concept of JavaScript!

Introduction

Prototypes in JavaScript are the mechanism to share standard functionalities between objects. Almost all objects in JavaScript are instances of Object. A typical object inherits all the properties and methods from Object.prototype. In simple terms, a prototype is an object from where JavaScript objects inherit methods and properties from.

Sounds like Greek? Well, don't worry. Go on. I've got you covered.

What is a PROTOTYPE?

When a function is created in JavaScript, the JavaScript engine adds a prototype property to it. This prototype property is an object called a prototype object with a constructor property by default. The constructor property points back to the function on which the prototype object is a property. We can access the function's prototype property using functionName.prototype.

Take this function as an example,

1_GhuZ3RS4yg7ErXHR0RLZAw.png

As you can see in the below diagram, the Person constructor function has a prototype property that points to the Prototype object. And in return, the Prototype object has a constructor property that points back to the Person function.

1_obSNNfL0Hemue9jwbTjPMA.jpeg

Let's see this in action,

1_VOTMWy0kTX1skSlwmUPc8Q.png

In the above screenshot, an object man is created from the Person function with the new keyword. You can clearly see a property __proto__. This indeed is the prototype property mentioned in the diagram above. I have explained this __proto__ property further below. It is quite evident that the __proto__ property is pointing to the prototype object, and the prototype object is containing the constructor of the Person function. I hope it all makes sense now.

How does it work?

When you access a property in an object, something called "Prototype Chaining" takes place. This is what happens.

  1. The property is first sought on the object as an own property
  2. If the property isn't found on the object, its prototype is checked next
  3. If the property doesn't exist on the prototype, the prototype of the prototype is queried
  4. This querying of prototype and its prototype continues until the property is discovered or the end of the prototype chain is reached, at which instance an error is returned.

For example, let's take the man object. If I access the name property of the man object, the JS engine checks whether it is the object's own property - which is in this case. Suppose the name property is not present in the object's own property. Then the JS engine checks the object's prototype until the property is found. Else an error is returned.

DID YOU KNOW?

When you take a string such as "Jane Doe", you will be able to access and executes methods such as toLowerCase, concat, slice because they are available in the String prototype object. Now you must be understanding what the prototype in String.prototype.slice() meant in the MDN Web Docs!!!

1_VQZ_G5RJMGAKYZzKPOKWVQ.jpeg Screenshot of the MDN Web Docs

__proto__ vs prototype

__proto__ is the actual property that is looked up during the prototype chaining. It is kind of like a pointer to the prototype object, which holds all the methods and properties.

When you use the new keyword to create an object, __proto__ is built using a prototype object. To be specific, the methods and properties are stored in the prototype property on the object's constructor function, not in the object instance itself.

Take a look at this example,

1_oKbZxgEUuOowmZ6njkR2WQ.png

I have added a new method to the prototype object, not the object instance itself. This method is a simple toString(), which returns the name and the job.

When you console.log(man.__proto__), which is the pointer to the prototype object, this is what you will receive.

1_Or7wjFD6D0EJYICPfB_tNQ.jpeg

You can clearly see a function in the property toString. This is what that gets called when I access man.toString().

Why should you use prototypes when working with objects and inheritance?

Refer to the previous example where I created a man and women object from the Person function constructor.

Instance 1

This is how it will look without the toString function I added to the prototype.

1_4TR5mbid15-FsaRh11oFtw.jpeg

Instance 2

When I add the toString property to the prototype, this is how the structure will look.

1_1m-51CHSp1yOAezH2YpTTw.jpeg

Instance 3

Suppose I add the toString property to the Person function itself. This is how things would look like.

1_ymZcmQQGLwJQIlsBr5pwxw.jpeg

You can clearly see the difference between instance 2 and instance 3.

When you do not apply a prototype, every time you create an object instance, all the properties are associated with the instance of the object. This means that they will be pointing to a different memory location for each object instance.

Imagine creating 1000 similar objects with repetitive functions like the toString I have used above. You can save lots of unnecessary memory usage by using prototypes. But keep in mind that you should know when to use this.

Conclusion

Prototypes are crucial in JS utilities and libraries. As I mentioned above, all objects in JS inherit the prototype object, which makes it a fundamental building block of JS.

I am aware that I am unable to fully explain this concept in this mere 5-minute piece. Hence I strongly advise you to follow the resources I have attached below.

I hope you got some idea about this mysterious prototype. Happy learning!

Resources