| home / programming / javascript / gr / column18 / 1 | [previous][next] |
While the previous example code demonstrated effectively how one class can inherit methods and properties from another, there was one method that was not inherited; the constructor. As the Derived instance is constructed in the line:
var d = new Derived(2);
the Base class's constructor will not be called and so any code in the Base() function that the Base class depends on will not be run. A way to resolve this is necessary.
The answer lies with the "call" method of the Function object:
// create a derived class inheriting from Base
function Derived(d, b)
{
// call Base constructor
Base.constructor.call(this, b);
// initialise Derived settings
this.d = d;
}
With the Derived constructor written this way, the Base class constructor will be called with its this pointer pointing to the Derived object instance.
The next issue to tackle is object identity, or how to tell what kind of class an object instance is. This can be useful for functions that process objects generically, but need to do specific processing on instances of a particular type. An object's prototype contains a 'constructor' property that identifies the function used to construct the object. This property provides part of the solution:
// construct an object
var o = new MyClass("my instance");
// test whether o is an instance of MyClass
var isMyClass = (o.constructor == MyClass); // isMyClass will be true
This code works well for simple objects but we run into a small problem when we consider inherited classes:
var d = new Derived(2,1);
var isBase = (o.constructor == Base); // isBase will be true
var isDerived = (o.constructor == Derived); // isDerived will be false
When inheriting the Derived class from Base, the Derived class's prototype is assigned to a new instance of Base and so the constructor property of any Derived instance will point to the Base constructor. The solution here is to reassign the Derived constructor in its prototype:
Derived.prototype.constructor = Derived;
With the Derived class constructor reset to the appropriate value, the tests above will reflect the correct value for isDerived but now isBase will be false. To fix that, you need to add a link from derived classes to the base classes ...
function Derived(d, b)
{
// call Base constructor
Base.constructor.call(this, b);
// initialise Derived settings
this.d = d;
}
// 'inherit' from Base by assigning an instance of Base to the prototype
Derived.prototype = new Base();
Derived.prototype.constructor = Derived;
// add link from Derived to Base
Derived.baseClass = Base;
Now, testing a class instance can follow the chain from its most derived class all the way to the top of the inheritance tree.
var isBase = false;
var pConstructor = d.constructor;
while ( pConstructor )
{
if ( pConstructor == Base ) { isBase = true; break; }
pConstructor = pConstructor.prototype.baseClass;
}
One finishing touch is to add the JavaScript Object class to the heirarchy:
function Base(b)
{
this.b = b;
}
Base.prototype = new Object;
Base.prototype.constructor = Base;
Base.baseClass = Object;
| home / programming / javascript / gr / column18 / 1 | [previous][next] |
URL: http://webreference.com/programming/javascript/gr/column18/1