Javascript OOP – Advanced

In the previous post we looked at the basics of creating classes and objects in Javascript. In this article we will see how inheritance can be  implemented. To truly appreciate this, We have to understand few basics of what is a function semantically.  What exactly is happening when you declare a function as below

function Person(){
         this.myname = "Vineel";
};

Lets make use of chrome web inspector console to fully understand what is happening. Inside chrome press Control+Shift+j  to open Chrome web inspector.

Chrome Web inspector
Chrome Web inspector

Paste the above code into the inspector and call console.dir(Person) . This console.dir function is used to get the internals of the any Javascript object or function.

Function as Objects
Function as Objects

Pause for a while and take a look at the highlighted rectangle containing various properties. Function containing properties may seem confusing at first for people who have experience in other programming languages. This is not true with Javascript. Currently what you are looking at is syntactically a function but semantically an object of type Function. Yes, In javascript even the functions you declare are just syntactic sugar on top of underlying Function objects. The properties that are shown in the Chrome inspector are nothing but the properties of the Function object created.

Function Internals
Function Internals

The most important properties of the above are the prototype and __proto__ These are the core for the current topic of interest.

Prototype

prototype  is the link to the Person class’s prototype(template). So if we create a function with Person as its name, Then Person.prototype  contains the template of how a Person will be. Note prototype does not include any of the properties(myname, work) that we declared in the Person function. The reason for this is every property that we declared gets created on the fly when the object of the function is created or when you run the Person() as a function. But since every prototype is an object it contains two important properties

  1. constructor
  2. __proto__
Object Constructor
Object Constructor
Function Prototype Internals
Function Prototype Internals

constructor property just acts as self pointer to Person function(cycle – try expanding constructor and then its prototype soon…) like a self pointer in C structures. __proto__ property acts like a pointer to its parent object which in this case is Object.  This __proto__ is the key for establish inheritance hierarchy.

Inheritance the Javascript way

Let us assume a Employee class which need to be a subclass of a Person. First declare both the classes separately as shown below.

function Person(){
	this.name = "Vineel";
	this.work = function(){
		console.log("Yes I work...");
	};
};
function Employee(){ };
Person & Employee
Person & Employee

Now what happens if we do the following

Employee.prototype = new Person();
Employee Hierarchy Hijacked
Employee Hierarchy Hijacked

The default object hierarchy Employee is hijacked with Person hierarchy. Isn’t this inheritance? Yes ofcourse – but only after few other modifications.
Firstly the contructor of the Employee got overwritten by Person object. So we need to patch it up as below.

Employee.prototype.constructor = Employee;

Once this inheritance link is established, Only then we need to declare any additional methods specific to Employee as shown below

Employee.prototype.salary = 10000;
Employee.prototype.printTotalWorkHours = function(){
      console.log("I work... "+ 24*7);
};

This is Javascript way of doing inheritance. There are many different ways in which we can achieve inheritance. This method of simulating inheritance with prototypes is called as  Prototypical Inheritance.

What happens when Employee object is created?

When you create a new Employee object using the new operator, Then we get a real object which contains the properties and methods that we have declared. Now when the hijacked Employee object is created, The internals of the object will be as shown below

Final Employee & Person Hierarchy
Final Employee & Person Hierarchy

__proto__ acts as an invisible link that makes inheritance possible. The methods of Person class can be accessed directly without the __proto__ link from the Employee. Note use of __proto__ directly is not recommended, Because it is implementation dependent and have some caveats.

Javascript object internals

Javascript Object Internals
Javascript Object Internals

The above picture gives complete rundown of how the connections are made between various objects involved before and after Object creation. The inheritance mechanism in Javascript is very flaky.  Things get very slippery when we start playing with multiple objects and multi level inheritances etc.

So the basic thing to remember for creating inheritance in Javascript is to play mindful with prototype object.

Hope this article helped in understanding the Javascript OOP internals better.

References:

  1. Douglas Crockford: “Advanced JavaScript” (1 of 3) (Google)
  2. Douglas Crockford: “Advanced JavaScript” (2 of 3) (Google)
  3. Douglas Crockford: “Advanced JavaScript” (3 of 3) (Google)
  4. Learning JavaScript Design Patterns By Addy Osmani
  5. http://stackoverflow.com/questions/4012998/what-it-the-significance-of-the-javascript-constructor-property

Leave a comment

Leave a Reply