Possibly evil classical inheritance in Javascript
Instead of doing my work like I should, I have come up with a possibly very evil pattern to implement classical inheritance in Javascript. I’m sure this has been posted somewhere before, or written in a book or something, but I may as well put it out there myself.
The idea is to use object literals like you would use classes, using a clone technique to create new instances based on the classes. That way each “instance” of the class is a separate javascript object, with no dependence on other objects. Goes faster, uses less memory. I added a tiny amount of sugar to allow for extending superclasses, making “static” clones of objects and using a constructor. I don’t vouch for the performance or the non-harmfulness of this pattern.
With this pattern you can actually make a class like this:
var myClass = {
memberVar:'',
_construct:function(args){
this.memberVar = args.str;
},
sayHi:function(str){
alert(str);
}
};
Then you can instantiate this using a pretty simple function I wrote (which I will show later):
var args = {str:'mystring'};
//syntax for makeNew:
// makeNew(obj myClass, bool static, obj args)
var myObj = makeNew(myClass, false, args);
myObj.sayHi('foo'); //result: "foo"
After the jump, extending superclasses:
To extend objects I set it up so you could have an “extend” member in the class, with a pointer to the class (object) you want to extend:
var mySubClass = {
extend:myClass,
sayHello:function (){
this.sayHi(this.memberVar);
}
}
var args = {str:'mystring'};
var myObj = makeNew(myClass, false, args);
var myObj1 = makeNew(mySubClass, false, args);
myObj.sayHi('foo'); //result: "foo"
myObj1.sayHello(); //result: "mystring"
Magic! You can chain objects as long as you want. The parent constructor is called by default, unless you specifically overwrite it in the child classes. The magic all happens in my “makeNew” function, which isn’t really read for more than a proof of concept, so use at your own risk:
//instantiate
var makeNew = function(obj, stat, args){
var s = stat || false;
var extend = false;
function F(){};
if(obj.extend !== undefined){
//yes, this is recursive, to support multiple inheritence
extend = makeNew(obj.extend, true);
F.prototype = extend;
}else{
F.prototype = obj;
}
var clone = new F();
//If we are extending, we clone the base class and add
//our methods to it.
if(extend){
for(item in obj){
clone[item] = obj[item];
};
}
//If this is static, don't execute the constructor
if(s !== true){
try{
clone._constructor(args);
}catch(e){
console.log(e);
}
}
return clone;
};