I Like Simple Inheritance

There are a lot of “ways” to implement inheritance in javascript thanks to the Constructors prototype property, and a lot of people has implemented amazing abstractions where is possible to call Parent Constructor methods etc.

I’m not saying these abstractions are the best way to code in Javascript (just ask the Yahoo guys), since Javascript object oriented nature was not thought to do it so. But sometimes it makes easier for not Javascript devs to work.

One of these abstractions is Simple Inheritance by John Resig.

I think is really cool because of its simplicity: a few lines of clean code that let you do things in Javascript you shouldn’t be doing :)

Let’s see it:

/* Simple JavaScript Inheritance
 * By John Resig http://ejohn.org/
 * MIT Licensed.
 */
// Inspired by base2 and Prototype
(function(){
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
  // The base Class implementation (does nothing)
  this.Class = function(){};

  // Create a new Class that inherits from this class
  Class.extend = function(prop) {
    var _super = this.prototype;

    // Instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    var prototype = new this();
    initializing = false;

    // Copy the properties over onto the new prototype
    for (var name in prop) {
      // Check if we're overwriting an existing function
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;

            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];

            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);
            this._super = tmp;

            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }

    // The dummy class constructor
    function Class() {
      // All construction is actually done in the init method
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }

    // Populate our constructed prototype object
    Class.prototype = prototype;

    // Enforce the constructor to be what we expect
    Class.prototype.constructor = Class;

    // And make this class extendable
    Class.extend = arguments.callee;

    return Class;
  };
})();

Ok, nothing extremely different from other implementations, what makes it easier to understand.

The 3 points I really like about it are:

    /xyz/.test(function(){xyz;})

That’s the way it checks the environment supports functions decompilation, in case it does and the code this._super() is found in the current object property code (of course, has to be a callable object), then the same named method will be called in the Parent Constructor when calling this object property.

    Class.prototype.constructor = Class;

That’s not needed from the functional point of view but it makes our Constructors more reliable.

    if ( !initializing && this.init )
        this.init.apply(this, arguments);

This condition makes possible the init method to be called just once on object creation via the new operator, since the way the Constructor prototype object is created consists in copying the object generated by new this() call (let’s say a “Parent Class” object).

One thing we could improve would be to name the Class.extend method like this:

    "use strict";
    Class.extend = function extend(prop) {
        var _super = this.prototype;

so we could do this:

    // And make this class extendable
        Class.extend = extend;

in order to avoid the deprecated arguments.callee property.

Another not JS nature improvement would be to clone every “[object Object]” or “[object Array]” property, instead of making objects to inherit shared references properties, so each instance would have an independent copy of these properties. In anycase I don’t think this makes a lot of sense…

0 comments ↓

There are no comments yet...Kick things off by filling out the form below.

Leave a Comment


1 * = two