JavaScript STL, Part 4 | 4 | WebReference

JavaScript STL, Part 4 | 4

Tidy Up

The code presented above will work but it's a bit messy. The process of inheriting one class from another and testing class type could best be placed in functions:

 

// inherit from a base class

Function.prototype.inherit = function(baseClass)

{

   // inherit the prototype of the base class

   this.prototype = new baseClass();

   

   // reset the constructor property

   this.prototype.constructor = this;

 

   // determine base class' name

   var baseClassName = baseClass.getName();

 

   // reference to base class

   this.prototype[baseClassName] = baseClass.prototype;

 

   // code required by instanceOf()

   this.prototype.baseClass = baseClass;

 

   // reference to this class

   this.prototype.classType = this;

   this.prototype.typeName = this.getName();

}

The code above defines a function called inherit that is attached to the prototype of the Function class. Remember, in JavaScript, functions are objects and their class type is "Function." Like any other class, we can add functions to its prototype for use by Function instances. For example, the Derived and Base code above can be written with more clarity...

// create a base class with one method

function Base(b)

{

   this.b = b;

}

Base.inherit(Object);

Base.prototype.foo = function() {...}

 

// create a derived class inheriting from Base

function Derived(d,b)

{

   this.Base.constructor.call(this,b);

   this.d = d;

}

Derived.inherit(Base);

Derived.prototype.bar = function() {...}

Testing for an instance's class can be wrapped into a function added to Object.prototype:

// return true if instance is a specific class or inherited from that class

Object.prototype.instanceOf = function(classType)

{

   if ( !this.classType ) return this instanceof classType;

 

   var ctor = classType.prototype.constructor;

   var p = this.constructor;

   while ( p )

   {

      if ( p == ctor ) return true;

      p = p.prototype.baseClass;

   }

   return false;

}

Object.prototype.instanceOf takes advantage of the properties assigned in the Function.prototype.inherit function. It also adds the feature that if the object has no classType property then the standard JavaScript instanceof operator will be used. Now, testing an instance object for its class type can be performed in a single line...

var b = new Base(1);

var isBase = b.instanceOf(Base);       // true

var isDerived = b.instanceOf(Derived); // false

 

var d = new Base(2,1);

isBase = d.instanceOf(Base);           // true

isDerived = d.instanceOf(Derived);     // true

Conclusion

The language of JavaScript offers a primative class mechanism using the prototype property where functions and properties may be shared across multiple instances of a given class. This article demonstrates how this feature may be extended to build complex class hierarchies where one class may inherit behaviour from another.

In part 2, you'll learn how to extend some of the inbuilt JavaScript classes (like String and Date) and introduce some useful techniques common to many object oriented languages.

Disclaimer

While I have endeavoured to make this code as browser compatible as possible, I have only tested it with Internet Explorer (6.0) and Netscape (8.0) as this represents a large proportion of users.

About the Author

Guyon Roche is a freelance web developer in London, Great Britain. He specializes in Windows platforms with an interest in bridging the gaps between different technologies. For more information, visit www.silver-daggers.co.uk. You can write to him at: guyonroche@silver-daggers.co.uk.

Created: March 27, 2003
Revised: February 17, 2006

URL: http://webreference.com/programming/javascript/gr/column18/1