Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / IIS

Better class-like inheritance support library for JavaScript

0.00/5 (No votes)
9 Mar 2012CDDL2 min read 8.5K  
Presenting library functions that circumvent some of the draw-backs of built-in JavaScript inheritance.

Introduction

JavaScript does not support classes, it works with prototypes that allow for fully dynamic object creation but if one wants to have a more class-like behavior a few tricks and work-arounds are needed.

The code was initially developed for use on the server side in Microsoft IIS (Jscript) and will also be adapted for client-side use (Browsers) and use in node.js, in future releases.

Basics: classic JavaScript inheritance

The easy way of inheriting from base "classes", as shown in most JavaScript programming guides: 

JavaScript
 1: function MyBaseClass()
 2: {   MyBaseClass.iUsageCount++;
 3:     return this;
 4: }

 6: MyBaseClass.iUsageCount=0;

 8: function MyDerivedClass()
 9: {
10: }

12: MyDerivedClass.prototype=new MyBaseClass();
13: //MyDerivedClass.prototype.constructor=MyDerivedClass;

15: var jDerivedInstance=new MyDerivedClass();
16: jDerivedInstance instanceof MyDerivedClass; //true
17: jDerivedInstance instanceof MyBaseClass; //true
18: jDerivedInstance instanceof Object; //true

Now let's have a look at the effects of this kind of inheritance:

  • Pro: Easy to implement, easy to remember, and also easy to forget writing line 13. 
  • Pro: instanceof works as expected.
  • Con: In line 12, the base class´ constructor is called and the usage count is set to 1, although we didn´t really want to create a "real" instance. 
  • Con: When not using line 13, instance.constructor would point to MyBaseClass, which is not correct. When using line 13, instance.constructor tells us the correct "class" name, but instance.constructor.prototype does not tell us the base class any more.
  • Con: On instantiation of the derived class in line 15, the base constructor is not automatically called -- we would have to call it explicitly.

A first improvement

Now we try fixing the first few things on the classic inheritance code:

JavaScript
[...]

 8: function MyDerivedClass()
 9: {   MyDerivedClass.__base__.call(this);
10: }

12: MyDerivedClass.prototype=Object.create(MyBaseClass);
13: MyDerivedClass.prototype.constructor=MyDerivedClass;
14: MyDerivedClass.prototype.__proto__=MyBaseClass.prototype;
15: MyDerivedClass.__base__=MyBaseClass;

17: var jDerivedInstance=new MyDerivedClass();

The changes in behaviour are now:

  • Pro: In line 12, Object.Create gives the benefit of creating the needed base class instance without calling its constructor.
  • Con: But in IIS and IE<9.0, Object.Create is not available, so we will show an emulation function in the next edition of this article.
  • Pro: In line 14, we set the de-facto-standard property "__proto__", so we get a path to walk the inheritance chain, when we need it. We also set a non-standard "__base__" property directly on the constructor, so it will be easy to call the base constructor (line 9).

A surrogate constructor helps

Don´t forget that under IIS and IE<9.0, we don't have "Object.create()". But we can use a so-called surrogate constructor to clone the class by its prototype without its original constructor.

JavaScript
[...]

 8: function Surrogate()
 9: {   //do nothing!
10: }

12: Surrogate.prototype=MyBaseClass.prototype;
13: MyDerivedClass.prototype=new Surrogate();
14: MyDerivedClass.prototype.constructor=MyDerivedClass;
15: MyDerivedClass.prototype.__proto__=MyBaseClass.prototype;
16: MyDerivedClass.__base__=MyBaseClass;

18: var jDerivedInstance=new MyDerivedClass();

We construct the Surrogate class instead of the base class for use as the derived class' prototype, so the base constructor is not called, as with Object.create, which we don´t have.

Next part: constructor chaining

In the next part of this article, we will look at how we can build a constructor chaining mechanism into our inheritance mechanism, so base constructors will be called automatically/implicitly, as known from languages such as C++ or C#.

Your comments are welcome!

History 

This is the original edition of the article.

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)