Differential inheritance in JavaScript

From MozillaZine Knowledge Base
Revision as of 04:13, 19 December 2004 by Asqueella (talk | contribs)
Jump to navigationJump to search

Differential Inheritance in JavaScript

Netscape 4.x and Mozilla both provide access to the internal prototype information associated with an Object in JavaScript using the __proto__ property. By manipulating this property, a developer can emulate "differential inheritance", a common technique in prototype-oriented programming models.

Differential Inheritance is a common prototype-oriented model that uses the concept that most objects are derived from other, more generic objects, and only differ in a few small aspects. Each object maintains a reference to its prototype and a table of properties that are different. The following code provides a simple method for "cloning" an object and a fundamental object, since the global variable Object actually refers to the Object constructor, not an actual Object.

Object.prototype.clone = function(){
    var newObject = new this.constructor();
    newObject.__proto__ = this;
    return newObject;
};
Root = new Object();

Using "clone", it becomes possible to simply derive more specific objects from a generic prototype. The following is a simple example of building up increasingly more specific objects using the clone method and differential inheritance.

Record = Root.clone();
Record.toString = function(){ return "a Record"; };

Person = Root.clone();
Person.firstName = false;
Person.lastName = false;
Person.toString = function(){ 
     if( this.firstName ){
         if( this.lastName ){
             return this.firstName + " " +this.lastName; 
         }else{
              return this.firstName;
         }
     }else{
         if( this.lastName ){
             return this.lastName;
         }else{
             return "a Person";
         }
     }
}

JoePerson = Person.clone();
JoePerson.firstName = "Joe";
alert( JoePerson.toString() );

A word of caution: Internet Explorer currently does not support the __proto__ property. It is recommended that this technique be reserved for situations where the developer can be certain that the script will be executed by Mozilla or other interpreters that support the __proto__ property, like Safari and KJS.