Skip to content

Instantly share code, notes, and snippets.

@ajainarayanan
Last active October 17, 2017 04:56
Show Gist options
  • Save ajainarayanan/dd1702c221784caa5c6458e88dc5057b to your computer and use it in GitHub Desktop.
Save ajainarayanan/dd1702c221784caa5c6458e88dc5057b to your computer and use it in GitHub Desktop.
Inheritance in Javascript

Originally posted on Sep 3, 2014

Today there was an interesting solution to the most basic problem in the javascript world.

The problem was to explain how inheritance works in javascript Javascript being pure object oriented language (In its true sense. Objects are first class citizens and there is no concept of 'classes'), the fundamental part of any class in javascript is two things.

  • prototype property.

  • constructor property.

The prototype property is nothing but the a chain (or list) that holds the current object's property and also a reference to Function.prototype which inturn holds a reference to Object.prototype. So when a property look up happens in any object in javascript it finds it at the first level and then moves up to Function and then up until Object. Object.prototype finally ends with a null thereby terminating the lookup chain.

Any function in javascript becomes a constructor when called with a 'new' keyword. So Ideally every function in javascript is a constructor and constructor.prototype again corresponds to Object.prototype.

The only difference between these two is that the former is not visible to the javascript developer and the latter is. What it means is prototype-chain-lookup is not visible and the Fucntion.prototype property is visible in the debugging(js) context.

So based on these two facts lets see how can this problem be twisted,

function Language(name, origin) {
  this.name = name;
  this.origin = origin;
}

Language.prototype.property1 = function property1() { ... }
Lanugage.prototype.property2 = function property2() { ... }

function DynamicLanguage(name, origin) {
  Language.prototype.constructor.apply(this, [name, origin]);
  this.weirdness = true;
  this.author = 'Anonymous';
}

So based on the above snippet when we create a new instance of DynamicLanguage it is bound of have the properties of Langauge along with it? Right?

The answer is Yes and No. The new instance will have the two properties defined in the constructor from Language class and not the prototype properties defined outside the constructor. What we are essentially doing here is to execute the constructor (a function) in this case the Language function in the context of DynanicLanguage. So the 'this' parameter inside the Langauge fucntion becomes the scope of DynamicLanguage.

The only piece that is missing here is the prototype property of Lanugage that needs to be added to DynamicLanguage.

function DynamicLanguage (name, origin) {
  inherit(Language, DynamicLanguage);
  this.weirdness = true;
  this.author = 'Anonymous';
}
 
function inherit(baseclass, childclass) {
  var _c;
  _c = childclass.prototype.constructor;
  childclass.prototype = baseclass.prototype;
  childclass.constructor = _c;
  baseclass.prototype.constructor.apply(instance, []);
}

We can further extend the 'inherits' utility to do a lot more efficient handling of inheritance of classes by adding it as part of Object prototype or as a framework which takes care of creating classes and their inheritance (for all the gimicks we can do with js :rolls_eyes:). A more elegant solution would be the general (common) one where we assign the prototype of base class to the childclass and re-assign the constructor back to the original constructor. But this needs to be done outside the constructor and from a 'classical' programmers perspective that must be a little weird :) Hence if you are wondering why i did not go about the regular solution. Something to think about.


Warning:

2015 went by and javascript world doesn't think about classes anymore. This is not to be used anywhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment