In the beginning there was duplication
As you can see both Person and Developer objects have votingAge property. This is code duplication. This is an ideal case where inheritance can be used.
Refactoring code to make use of prototype method
Currently Person function is defined like this.
Problem with above code is that every time a new instance of Person is created, two new properties are created and they take up memory. If a million objects are created then all instances will have a property called
votingAge even though the value of votingAge is going to be same. All the million person instances can refer to same votingAge method if that method is define in prototype. This will save a lot of memory.
votingAge inside the person object and would have found it. Now the engine will not find
votingAge property inside the person object. Then engine will look for person.prototype and will search for
votingAge property there. It means, in the modified code engine will find
votingAge method in the second hop instead of first hop.
Bringing inheritance using prototype property
Currently Person is defined like this.
If Developer Object wants to extend Person then all that needs to be done is this.
Now Developer instance will have access to
votingAge method. This is much better. Now there is no code duplication between Developer and Person.
However notice that looking for
votingAge method from a Developer instance will take an extra hop.
- Next engine will look for votingAge property in its prototype property of Developer instance which is an instance of Person. votingAge method is not declared in the Person instance.
- Next engine will look for votingAge property in the prototype of Person instance and this method would be found.
Since only the methods that are common to both Developer and Person are present in the Person.prototype there is nothing to be gained by looking for methods in the Person instance. Next implementation will be removing the middle man.
Remove the middle man
Here is the revised implementation of Developer function.
In the above case Developer.prototype directly refers to Person.prototype. This will reduce the number of hops needed to get to method
votingAge by one compared to previous case.
However there is a problem. If Developer changes the common property then instances of person will see the change. Here is an example.
In order to solve this problem Developer.prototype should point to an empty object. And that empty object should refer to Person.prototype .
Solving the problem by adding an empty object
Here is revised implementation for Developer object.
Let’s test this code.
As you can see with the introduction of empty object, Developer instance have votingAge of 18 while Person intances have votingAge of 21.
If child wants to access super object then that should be allowed. That can be accomplished like this.
Capturing it as a pattern
The whole thing can be captured in a helper method that would make it simple to create inheritance.
Pure prototypal inheritance
A simpler form of pure prototypal inheritance can be structured like this.
Before adding the create method to object, I checked if this method already exists or not. That is important because
You can see that Object.create takes only one parameter. This method does not necessarily create a parent child relationship . But it can be a very good tool in converting an object literal to a function.