Wednesday, February 10, 2016

Object prototypes in JavaScript

In this post we will try to understand how to make use of JavaScript's Object prototypes to achieve code re-use i.e. to do Object (Oriented) programming[1].

It would be very useful read this without thinking of Java's notions of OO.

In JavaScript, we do not need special constructs( such as classes)  to create instances/objects. If we want an object, we just create one like so
1
2
3
4
5
6
7
var myCar = {
 numGears: 4,
 drive: function(){
  console.log('driving');
 }
}
myCar.drive(); // driving
And then another
1
2
3
4
5
6
7
var yourCar = {
 numGears: 5,
 drive: function(){
  console.log('driving');
 }
}
yourCar .drive(); // driving
No classes, no new keyword, no constructor function... plain and simple.
We can do better.. you would have noticed that the drive method(its really just a regular function) is repeated in the objects. It is the exact same code.  As we all know, code duplication is the enemy of the programmer. 
To facilitate sharing this function across the 2 objects, lets first pull this function out into a separate object. Lets call this object CarPrototype
1
2
3
4
5
var CarPrototype = {
 drive: function(){
  console.log('driving');
 }
}
The way to read CarPrototype would be as the object where we would add common functionality of car-type objects. 
Its not accidental that I used the phrase "Prototype" in "CarPrototype". More on that soon.
Now to make use of this shared object among myCar and yourCar objects, we would conceptually need the following.



i.e. more generically stated, we need a way to link objects to other objects[2].

Object.create


There is language support to achieve the above linking using the Object.create[3] function
As the name indicates, its used to create objects. Lets re-create myCar and yourCar using this.
1
2
3
4
5
var myCar = Object.create(CarPrototype);
myCar.numGears = 4;

var yourCar = Object.create(CarPrototype);
yourCar.numGears = 5;
Lines 1 and 4 do the following couple of things:

  1. Create and return a new object just like the humble object literal - { }
  2. And also create the linkage (thats shown as a dotted arrow in the picture above) from myCar and yourCar to CarPrototype

This linkage is the one of the most important concepts in JavaScript. It is known as prototype relationship between objects. Hence the reason for me to name the shared object as CarPrototype

Good-to-know facts about the prototype link
  • It is referred to as [[Prototype]] in the official spec
  • It is available via the __proto__ property (pronounced as dunder-proto) like so: 
    • myCar.__proto__
  • It can also be accessed using the Object.getPrototypeOf function like so:
    • Object.getPrototypeOf(myCar)
  • It is often confused with the prototype property that functions have

Foot-note:

[1] It was tempting to title this post as Object-oriented programming in JavaScript.. but I realized that it would have disappointed the Java developers who would stumble across it in their search to understand how to create classes in JavaScript.
[2] Kyle Simpson has formalized this into what he terms as OLOO (Objects linked to Other Objects) in his excellent You dont know JS series. 
[3] I wanted to link to the MDN doc for this but I refrained from doing so because at the time of this writing, their example highlights a class-style pattern which at best leaves a reader confused and at worst could lead new developers into assuming that its the MDN-recommended way.

No comments:

Post a Comment