Wednesday, May 25, 2011

Inheritance and virtual functions in javascript

Javascript has no built-in facilities for inheritance or virtual functions. Inheritance lets you define common functionality in a base class that can be extended or modified in a derived class. A virtual function is a function that can be redefined in a derived class and will correctly be called on an instance of that class. Although crude virtual functions can be done by assigning a different function to the object, calling the base class implementation becomes harder.

I've come up (although it might already be popular, I'm not entirely sure) with a scheme to create hierarchies with virtual function tables. Although it requires more typing and some discipline, it emulates inheritance and virtual functions correctly.

A class that is meant to be derived from is defined as a regular function, taking the derived class's this object as a parameter.

function inherit_base(self)
{
  self.member = 1;

  self.base__frob = function()
  {
    alert("frobbing base");
  }

  self.frob = self.base__frob;
}

function derived()
{
  inherit_base(this);
 
  this.frob = function()
  {
    this.base__frob();
    alert("frobbing derived");
  }
}

var d = new derived();
d.frob();

The "virtual function table" is defined at the end of inherit_base. The derived class can call the base's implementation while adding functionality.

If the base class can either be derived from or instantiated (that is, it is not what's commonly called abstract),
then a base class can be defined and derived from inherit_base:

function base()
{
  inherit_base(this);
}

This requires discipline: functions in the base class need to have a distinct name (here I use the base__ prefix) and be assigned to the "virtual" function's name afterwards. As with most languages, the base class implementation needs to be called manually from the derived class.