Helma Logo
main list history

Alternative Lazy JavaScript Inheritance

Lazy Inheritance is an approach intended to simplify writing OOP and provides support of prototype-based classes hierarhies, automatic resolving and optimizing classes dependencies.

Overview

"Lazy inheritance" is a design pattern used in JavaScript computer programming. It designates a postponed linking of an object with it's prototype (class) until it is needed. If used properly, such approach may increase efficiency, simplicity and flexibility of OOP based code written using JavaScript. Unlike of classical prototype-based approach, it supports a "Lazy" way of inheritance implementation, since reference to parent class is invoked only at the moment of object instance creation.
Basically, it's possible to say that instances of objects in such approach are created in "mixed" mode – on first invocation, an appropriate factory is used to modify object constructor prototype which is later used for subsequent object instances creation.
Moreover, since "Lazy inheritance" is called only once at the moment of first object instance creation, it becomes possible to combine process of class prototype creation with resolving necessary dependencies of that class. In other words, the process of prototype construction also allows loading scripts (if ones were not loaded before) which particular class depends on.

Benefits

Such approach to inheritance support has the following benefits:

Lazy Inheritance Internals

"Lazy inheritance" is invoked within the Object' constructor code and is called only once for first object instance creation.
After invocation, the following steps:

The derived instance of the Object may be modified in the constructor according to particular logic. For example, some properties of the object may be defined.
The resulting object is the same JavaScript object as it would be created with prototype-based inheritance.

Example

First, we define Person.
Let's assume that declaration of that class is placed to person.js JavaScript file.

   /**
    * Constructor for Person class
    */ 
   function Person(aName)
   {
     this.fName = aName;
   }
   /**
    * Function which returns name of Person’s.
    */
   Person.prototype.getName = function()
   {
     return this.fName;
   };
   /**
    * Here we define function which returns 
    * string representation of Person
    * assign it to prototype of Person class
    */ 
   Person.prototype.toString = function()
   {
     return "Person: " + this.getName();
   };

Here we assume that the code below is placed to employee.js file.

  /* 
   * Here we define that Employee class 
   * depends on person script. 
   */ 
  JSINER.addDependency( {Employee:"person"} );
  /**
   * Here we define constructor for Employee class 
   * and declare that Employee class inherits Person one
   */ 
  function Employee(aName, aUID)
  {
    var self = JSINER.extend(this, "Person");
    self.fName = aName;
    self.fUID = aUID;
    return self;
  }
  /** 
   * Here we define function which return UID of employee 
   * and assign it to prototype of Employee class.
   */    
  Employee.prototype.getUID = function()
  {
    return this.fUID;
  };
  /**
   * Here we define function which returns 
   * string representation of Employee
   */
  Employee.prototype.toString = function()
  {
     var person = Employee.superClass.toString.call(this);
     return this.getUID() + ":" + person;
  };

And this is sample HTML page which uses declarations of JavaScript object above:

  <html>
    <head>
      <title>Lazy inheritance example.</title>
       // We need to include reference to JSNIER code
      <script src="script/jsiner.js"></script>
      // Note that we include reference to 
      // script that contains Employee class only
      <script src="script/employee.js"></script>
      // And no it's not required to 
      // reference person.js script explicitely -
      // JSINER will resolve and load it automatically
      <!--<script src="script/person.js"></script>-->
   </head>
   <body>
     <script>
        var employee = new Employee('John Doe', 1212);
        alert(employee);
      </script>
   </body>
 </html>

During execution of example code listed above, linkage of Employee and Person as well as
loading of necessary script "person.js" is performed automatically with the first creation of Employee instance.

As it is illustrated by examples above, "Lazy inheritance":

In general, the proposed scheme considers "lazy" loading as primary mode for loading particular scripts. However, this is not strict requirement – it is also possible to force loading of all scripts which form particular application before starting objects creation if this way of loading is required by particular application architecture.

Where it works

Proposed Lazy inheritance approach was tested under

Lazy Inheritance Implementation