In the Previous Tutorial, we explored Getters and Setters in JavaScript. In this tutorial, we’ll learn about Prototypes in JavaScript.
is one of the most important aspects of Object-oriented programming. Unfortunately, JavaScript does not implement inheritance the same way as other modern programming languages like Java, C#, Python, etc do. In JavaScript, inheritance is implemented through Prototyping. There is huge hue and cry about Prototyping in JavaScript community for being so confusing and intimidating. This is partly because lots of online tutorials speaks of Prototyping as if they are CocaCola’s secret formula.
In this tutorial we’ll keep things simple and learn Prototypes by building a small application – a car factory.
Let us run this code in the browser console and build two cars.
function Car(make, model) {
this.make = make;
this.model = model;
this.run = function() {
console.log('Car is running');
}
}
const c1 = new Car('Volkswagen', 'Polo');
const c2 = new Car('Toyota', 'Corolla');
Let us inspect both object c1
and c2
in the console:
It is looking as expected, right? Both objects have make
, model
and run
properties. In fact, run
is a method.
Hell No!!! What is that __proto__
thing?
Let us keep aside that weird __proto__
property for a moment. We’ll explain it in a few minutes.
The real issue is both objects have their own property run
. They also have their own make
and model
properties but they are unique for both cars. Do we really need the duplicate properties run
for both objects? Isn’t it would be efficient to keep that property run
somewhere else that both objects can share.
That somewhere else is the prototype of that object. We can add the run
property to the prototype of the constructor function Car
(remember in JavaScript a function is also an object) and remove it from the function:
function Car(make, model) {
this.make = make;
this.model = model;
}
Car.prototype.run = function() {
console.log('Car is running');
}
const c1 = new Car('Volkswagen', 'Polo');
const c2 = new Car('Toyota', 'Corolla');
If we refresh the browser and run this code in the browser console, both objects c1
and c2
will have two direct properties make
and model
and they will share the run
property. In fact all objects created by Car
will share the same run
propertybecause this property is added to the constructor function’s prototype.
If you run c1.run()
and c2.run()
, you should be greeted with this message in both cases:
Car is running
Let us inspect c1
and c2
again in the browser console.
Where is the run
property man? How come c1.run()
is still working?
If we expand the __proto__
property for both objects c1
and c2
, there we’ll find it.
The
__proto__
property of an object refers to its prototype, that is theprototype
property of the function used to create that object.
In our case, the __proto__
property of objects c1
or c2
refers to the propertyprototype
of function Car
If we execute these statements we should be greeted with true
:
c1.__proto__ == Car.prototype; //true
c2.__proto__ == Car.prototype; //true
Note: Just to be sure there are two underscores __
surrounding proto
.
If we try to look up a property in an object, the JavaScript interpreter first tries to find it in that object’s own property, then looks for it in the object’s prototype. In our case, the JavaScript interpreter first tried to find run
in c1
‘s own properties, it did not find it there so it tried to find it in its prototype Car.prototype
and it was successful.
We can confirm if a property is defined as the object’s own property by running this command:
c1.hasOwnProperty('make'); //true
c1.hasOwnProperty('run'); //false
Wait! How come c1
has got hasOwnProperty
property? We did not define it in Car
.
Well, that is an intelligent question. It is due to the prototypical chain. Let me explain it.
If you have followed This Tutorial, you know that the constructor functions are created by a special constructor Function
this special constructor Function
created by another special constructor Object
That is why we call in JavaScript, everything is an object (except primitives).
Since every object in JavaScript is derived Object
in the Prototypical Chain, Object.prototype
is the last prototype to look for.
When we c1.hasOwnProperty
the JavaScript interpreter tries to find it in c1
‘s own property. It fails to find it there so it tries to find it in its prototype Car.prototype
(c1.__proto__
just a reference to Car.prototype
). The hasOwnProperty
is still not found in Car
‘s prototype
. The JavaScript interpreter tries to find it upwards in the Prototypical Chain Car.prototype.__proto__
is just a reference Object.prototype
and it finds it there.
Guys, we hope this tutorial was able to help you understand Prototypes in JavaScript. In the Next Tutorial, we’ll extend these learning and implement Inheritance by using Prototypes.