Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pros and cons of inheritance modeling in Javascript?

I realize that Javascript does not have classes and is not built to have classical OOP inheritance. But I find such patterns so useful that I wanted to build a simple way to model that kind of behavior, ideally while leveraging the best parts of Javascript's flexibility. What are the pros and cons of the following approach?

I have the following functions in my custom library:

function inherit(superClass, args, instance) {
    var subClass = inherit.caller;
    var o = new superClass(args);
    for(p in o) {
        if(o.hasOwnProperty(p)) init(instance, p, o[p]);
        else init(subClass.prototype, p, o[p]);
    }
}

function isUndefined(x) {var u; return x === u;}

// sets p to value only if o[p] is undefined
function init(o, p, value) {if(isUndefined(o[p])) o[p] = value;}

This setup requires two conventions:

  1. Functions that are modelling classes must take one argument: an object with named properties
  2. Functions wishing to "inherit" from another must call the inherit function.

Here's an example of what you get as a result (paste into the Firebug command line, along with the library functions, to see it in action):

function SuperClass(args) {
  this.x = args.x;
}

SuperClass.prototype.p = 'SuperClass prototype property p';

function SubClass(args) {
  inherit(SuperClass, args, this);
  this.y = args.y;
}

SubClass.prototype.q = 'SubClass prototype property q';

var o = new SubClass({
  x: 'x set in SuperClass',
  y: 'y set in SubClass'
});

console.dir(o);  // correctly has properties x, y, p, and q

['x', 'y', 'p', 'q'].forEach(function(prop) {
  // true for x and y, false for p and q
  console.log("o.hasOwnProperty('" + prop + "')", o.hasOwnProperty(prop));
});

console.log("o instanceof SubClass: ", o instanceof SubClass);      // true
console.log("o instanceof SuperClass: ", o instanceof SuperClass);  // false

I am aware of the following cons:

  1. Modifying the super class prototype will not affect your instance object, as you might expect from prototype-style inheritance
  2. The instance object will not register as instanceof the super class (although it will still quack like one)
  3. The argument conventions might be annoying

and pros:

  1. Requires only one function call (easy to implement)
  2. Differentiates between prototype properties and instance properties
  3. Arguments passed to the sub class are also passed to the super class
  4. Instance properties set by the super class constructor are immediately available in the sub class constructor
  5. Multiple inheritance is easy, just call inherit multiple times in your sub class
  6. Doesn't over-write existing properties of the sub class

Pros 3 - 6 specifically make this method more useful for me than the SubClass.prototype = new SuperClass() method. Other methods, like dojo's class modelling, are much more complicated, I think unnecessarily so.

So, tell me what you think. And if someone else has done this before, please let me know, I haven't intended to duplicate any ideas.

like image 746
Chris Avatar asked Nov 03 '10 15:11

Chris


2 Answers

Those coming here to see simple and probably best way to do inheritance in javascript please read the following, its so much simpler than everything else I've scanned through:

http://javascript.crockford.com/prototypal.html

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

N.B: Object.create is now part of javascript in newer browsers, but by adding the above the following also works in older browsers.

newObject = Object.create(oldObject);
like image 50
Darren Avatar answered Oct 19 '22 13:10

Darren


You might want to look at what John Resig has done with JavaScript inheritance: http://ejohn.org/blog/simple-javascript-inheritance/

It's the best attempt at Javascript inheritance that I've seen.

like image 41
brendan Avatar answered Oct 19 '22 14:10

brendan