Prototype in JavaScript

prototype

We know Prototype means partially completed model piese to test a concept or process so that time to time we change it and make the final product out of it. On the other hand, in JavaScript world prototype is used to make object inheritance, that will open up many grate new features and more language flexibility. Let’s look at how JavaScript prototype works under the hood.

Let’s create basic element of JavaScript as below.

function Foo(name){
 this.name = name;
}

We know typeof Foo gives as "function" and when doing dir(Foo) shows some extra properties on it.

From Where these prototype and __proto__ came?
Basically JavaScript engine assigns these additional properties into the function object when evaluate particular function code block.

prototype property

Every javascript function has this property which is just an object pointing back to its original constructor function. To prove this, let’s look at below code.

You can see that, Prototype is a just an Object which has constructor function which point back to its original function. To make it more clear, just look at below picture.

__proto__ property

Let’s create an instance using Foo constructor function.

function Foo(name){
 this.name = name;
}

var objFoo = new Foo('foo');

When doing dir(objFoo) it shows that __proto__ property on it.

So that every object initialize from Foo function has __proto__ property which points to Foo.prototype object. That used to travels though __proto__ object to find method or property on its parent function object.

Now things are getting really interest, in several places, I have mentioned function object If I say JavaScript function are just an object, do you believe it? so in this case, typeof will not help.

We know that in JavaScript object, we can assign property using dot notation for bracket notation. I’m doing same thing for Foo function.

Or

It worked. So that mean functions are just holding key/value pairs. Other point is to make this statement true is __proto__ property on Foo function, which points back to it parent object which is Function.prototype.

That mean JavaScript Functions are Object which are instnace of Function function. but it has some specia behaviour. Such as name keyword is reserved for holding function name. argument holds the function parameters.

Do you think what will be the last object of this prototype chain ? That will be Object function prototype.

Now we can think JavaScript is like a nested objects tree which hanging each other through __proto__ property. At the top of the chain, Object.protoype which provide most of the basic methods and properties to all other none primitive types. If I visualize prototype chain, it looks like this.

How do we use prototype?

Adding functionality to instance of a function

Let’s assume we have function call Animal. using that we have created two object instances – cat and dog.

function Animal(name, sound){
  this.name = name;
  this.sound = sound;
}

var cat = new Animal('cat', 'meow');
var dog = new Animal('dog', 'bow wow');

Now we want to print each animal sound on console. We can do that in many ways. But what is the best and optimum way to do it. We can use prototype property of Animal. So whatever add to prototype property available to instance of that function object.

function Animal(name, sound){
  this.name = name;
  this.sound = sound;
}

var cat = new Animal('Cat', 'meow');
var dog = new Animal('Dog', 'bow wow');

Animal.prototype.makeSound = function(){
 console.log(this.name + " says " + this.sound);
}

cat.makeSound();  // Cat says meow
dog.makeSound();  // Dog says bow wow

Adding functionality to build in function

We can expand build-in function by adding new functionality e.g. Array, Data, Object. so that it’s available for all instance.

Array.prototype.remove = function(index) {
  var index = this.indexOf(index);
  if (index > -1) {
    this.splice(index, 1);
  }
  return this;
}

['Apples', 'Bananas', 'Avocados'].remove('Bananas'); //['Apples','Avocados']

Method borrowing

We can reuse build in function algorithms when every we need it.
E.g. – If we need to add join functionality to our own object, we can borrow from Array function prototype. Because it only consider length and index from outside.

Keep in mind that, every object has single prototype property, we can only point one object to another one. So that mean JavaScript supports single inheritance.

var obj = {
 0 : "Apples",
 1 : "Bananas",
 2 : "Avocados",
 length: 3,
}

obj.join = Array.prototype.join;

obj.join(); // "Apples,Bananas,Avocados"

In JavaScript, prototype is very powerful concept to use in handy, on the other hand, since JavaScript types are mutable, we may mistakenly overwrite existing functionality.

Summarize

In JavaScript, everything other than primitive are Objects and in this case Functions are treated as special kind of Object, It has two properties, prototype – which points back to original function though constructor and __proto__ points to its parent object which is Function.prototype.

Prototype makes language flexibility such as method borrowing, expanding built in functions and add new functionality to all instance. However, there are hight chances to overwrite existing functionality when we do it unintended.

Leave a Reply