Reputation: 7288
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:
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:
and pros:
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.
Upvotes: 9
Views: 2292
Reputation: 9499
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);
Upvotes: 4
Reputation: 92274
You know the cons of what you posted.... So take a look at my blog for a thorough explanation of what I think is the best way while describing the flaws of other patterns
http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html
Example:
//Abstraxct base class
function Animal(name) {
this.name = name;
}
Animal.prototype.sayMyName = function () {
console.log(this.getWordsToSay() + " " + this.name);
}
Animal.prototype.getWordsToSay = function () {} // abstract
// --------------------------------
function Dog(name) {
// Call the parent's constructor
Animal.call(this, name);
}
extend(Dog, Animal, {
getWordsToSay: function(){
return "Ruff Ruff";
}
});
The code I posted is an example syntax. The blog posts goes into details about how to add syntactic sugar.
The important things are:
Upvotes: 0
Reputation: 29986
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.
Upvotes: 3