JavaScript OOP Tutorial: Inheritance Using Closures

This is a JavaScript DOM exercise from Chapter 3 of Microsoft AJAX Library Essentials: JavaScript in ASP.NET AJAX 1.0 Explained.

In classic OOP languages such as C#, C++, or Java, you can extend classes through inheritance. Closure-based inheritance is implemented by creating a member in the derived class that references the base class, and calling that member. This causes the derived class to inherit all the base class members, effectively implementing the concept of inheritance.

To demonstrate this technique, weíll implement two classes: Car and SuperCar. The Car class constructor receives a car name as parameter, and it has a method named Drive. The class SuperCar inherits the functionality of Car, and adds a new method named Fly, reflecting the additional functionality it has in addition to what Car has to offer. The following diagram describes these two classes:

JavaScript Inheritance Class Diagram
Figure. Car and SuperCar class diagram

Remember that in JavaScript the implementation of a class diagram can be implemented in multiple ways. The code reflects the concept of the diagram, but not also the implementation details, as the C# code would. Hereís a possible implementation of Car and SuperCar:

<script type="text/javascript">
  // to be used as the Drive method of Car
function Drive()   {
    document.write("My name is " + this.Name + 
                   " and I'm driving. <br />");
  // class Car
  function Car(name)
    // create the Name property
    this.Name = name;
    // Car knows how to drive
    this.Drive = Drive;

  // to be used as the Fly method of SuperCar
  this.Fly = function()
    document.write("My name is " + this.Name + " and I'm flying! <br />");

  // class SuperCar
  function SuperCar(name)
    // implement closure inheritance
    this.inheritsFrom = Car;
    // SuperCar knows how to fly
    this.Fly = Fly;
  // create a new Car and then Drive
  var myCar = new Car("Car");

  // create SuperCar object
  var mySuperCar = new SuperCar("SuperCar");

  // SuperCar knows how to drive

  // SuperCar knows how to fly

The exercise demonstrates that inheritance really works. SuperCar only defines the capability to Fly(), yet it can Drive() as well. The capability to Drive(), and the Name property are inherited from Car.

At the first sight the code can look a bit complicated, especially if youíre a C# veteran. The Drive() and Fly() functions arenít defined inside Car and SuperCar, as youíd do in a C# class. Instead, we stored these methods/functions in the global context, and referenced them in Car and SuperCar, to avoid the memory leaks that were discussed earlier in this chapter. You can, however, define Drive() inside Car, and Fly() inside SuperCar, without losing any functionality.

If you comment the execution of this.inheritsFrom() from SuperCar, it won't inherit the capabilities of Car any more. If you make this test in FireFox, you'll see the following eloquent error message in the Error Console window of Firefox:

Firefox Error Console showing failed inheritance
Figure. Signs of failed inheritance

The problem with the presented inheritance solution is that itís not very elegant. Writing all functions and classes in the global context can quickly degenerate into chaos; and things get even more complicated if you want to have classes that have functions with the same name. Needless to say, this isnít something you need to be dealing with when writing your code. Luckily, JavaScript has a very neat feature that allows us implement inheritance in a much cleaner way: prototyping.

Implement the exercise step by step and find detailed explanations in our book, Microsoft AJAX Library Essentials: JavaScript in ASP.NET AJAX 1.0 Explained.