A detailed explanation of Object Prototypes in JavaScript — one you were waiting for!

Codeguage
5 min readOct 22, 2018

--

If you are tired of seeing different explanations of JavaScript prototypes and really don’t understand what’s going on then you have luckily arrived at the right place.

What will you learn in this page?

  • What are prototypes
  • Purpose of prototypes
  • How to work with prototypes
  • Prototypes of prototypes

Before beginning make sure you have a solid grip on:

Amongst the trickiest of concepts to grasp in JavaScript are prototypes.

They are tricky because have a lot of key details to be entertained — not because they are difficult to understand. Many people get stuck in the details about this prototype game so it is highly recommended to take things step by step.

Well prototypes are actually easier than they seem to be and at the end of this chapter you will definitely also agree to this fact.

So why waste more time?

What is a prototype?

In simple and comprehensive terms:

A prototype is an object from which other objects inherit properties and methods.

We have emphasized on two key terms — object and inherit.

  1. Prototypes aren’t numbers, strings, booleans, arrays or functions. They are pure objects.
  2. Objects inherit properties from their prototype i.e the properties on the prototype are accessible on the object too. You will understand this term much better as the chapter progresses.

Why care about prototypes?

Consider the following example from the previous constructors chapter:

function Book(name, genre, pages, id) {
this.name = name;
this.genre = genre;
this.pages = pages;
this.id = id;
this.displayInfo = function() { return "Name: " + this.name + " Genre: " + this.genre + " Pages: " + this.pages; }
}
var book1 = new Book("Web Designing Guide", "General Knowledge", 156, 3156); // has its own displayInfo() methodvar book2 = new Book("JS Skills", "General Knowledge", 500, 1052); // has its own displayInfo() method

Although the code runs perfectly fine, there is a slight problem in it.

Each time we create a new instance of the constructor Book() we create a new method displayInfo for the new object created. What this means is that if we have 100 object instances of Book(), for each of them we have one seperate displayInfo method stored seperately in memory.

Let’s demonstrate this even better using Object.getOwnPropertyNames() method which simply takes an object and shows all its OWN properties. With the above code written add the following lines.

console.log(Object.getOwnPropertyNames(book1)) // ["name", "genre", "pages", "id", "displayInfo"]console.log(Object.getOwnPropertyNames(book2)) // ["name", "genre", "pages", "id", "displayInfo"]

As you can see for both book1 and book2 we have seperate displayInfo() methods.

So when all the methods are doing the same thing why create them again and again and waste memory. Why not become more memory efficient when the solution is extremely easy? And this is where prototypes introduce themselves.

Prototypes in action!

We said earlier that objects inherit properties and methods from their prototypes, so in solving the example above, why not define displayInfo() on the prototype of book1 and book2 and all the instances of Book so that these objects can inherit it.

This part is crucial so let’s go over it again. Attention Required!

  1. Objects inherit properties from their prototype object so
  2. Instead of defining displayInfo() on the constructor Book() as we did earlier
  3. Let’s define it on the prototype of book1 and book2 which are the instances of Book()
  4. So that they can inherit it.

Didn’t even understand yet? Let’s implement this in real code now.

function Book(name, genre, pages, id) {
this.name = name;
this.genre = genre;
this.pages = pages; this.id = id;
} // Same constructor with removed method
// displayInfo() method on the prototype object
Book.prototype.displayInfo = function() { return "Name: " + this.name + " Genre: " + this.genre + " Pages: " + this.pages; }

var book1 = new Book("Web Designing Guide", "General Knowledge", 156, 3156); // has a displayInfo() method, but not its own
var book2 = new Book("JS Skills", "General Knowledge", 500, 1052); // has a displayInfo() method, but not its own

First we have the same constructor definition as before but now without the displayInfo() method. Then we have the main ingredient — the prototype. Now again attention is required over here!

Book.prototype is the PROTOTYPE OBJECT FOR THE INSTANCES OF Book() like book1, book2 etc.

IT IS NOT THE PROTOTYPE OF Book.

Many people confuse the prototype property as taking to an object’s prototype like so accessible owing to prototypal inheritance.

How does prototypal inheritance work?

It is good to know how this inheritance works.

There is no rocket science to how inheritance works in JavaScript. It is very simple. The whole idea is that when a property is called on an object, it is searched for in that object’s own properties first. If it’s found well and good, but if it’s not found then search begins on the object’s prototype. If the property isn’t even found there then search begins on the prototype of the prototype i.e one level further down. And this goes on until we reach the end which is Object.prototype. Nothing there means the property is undefined

In this way properties can travel across objects that are interconnected in what we call the prototype chain.

This whole section was the trickiest part where many people get stuck. Hopefully you didn’t. But how to get to the prototype of an object via the object’s name. Developers have thought of that!

In the examples above we said that book1.prototype doesn’t take to the prototype of book1. So how to get to that prototype? Well we have two ways.

Object.getPrototypeOf() method

This method takes a single argument that is the object whose prototype you wish to see and accordingly returns its prototype object. So for book1 (or even book2) we can now safely and directly visit it’s actual prototype like so:

Object.getPrototypeOf(book1); // Takes to the prototype of book1 which is actually Book.prototype

Now as you know that the prototype of book1 is Book.prototype why not even check that do the two objects, Book.prototype and the one returned by Object.getPrototypeOf(book1), match.

Book.prototype === Object.getPrototypeOf(book1); // true

And yes they do! This justifies the fact that Book.prototype is the prototype of book1. Go on and try this with book2!

And let’s even clarify further that Book.prototype is not the prototype of the function Book.

Book.prototype === Object.getPrototypeOf(Book); // false

To add properties to the prototype of book1 (and all other instances of Book) we can also use Object.getPrototypeOf(book1) and define stuff on it like so:

Continue reading..

Originally published at www.codeguage.com.

--

--