I was wondering for quite some time how to clean up the below code without blowing it up any further. The extension of the classes is the main concern here, it looks a bit too much like magic. That's mainly because it has to handle all the different cases, and I haven't figured out a way to reduce the code in a meaningful fashion here.
Maybe I'm paranoid and the code is just fine, but I'd still love to get some feedback on it.
The original code and test cases are here.
function is(type, obj) {
return Object.prototype.toString.call(obj).slice(8, -1) === type;
}
function copy(val) { /* ...make shallow copy */ }
function wrap(caller, obj) {
obj = obj || Function.call;
return function() {
return obj.apply(caller, arguments);
};
}
function Class(ctor) {
// ...default ctor stuff here....
function clas(args) { /* ...actual instance ctor stuff... */}
var proto = {};
clas.init = wrap(ctor);
// extend needs to be reduced in width, it easily goes over 80 columns
// without some ugly if statements
clas.extend = function(ext) {
if (is('Function', ext)) {
return ext.extend(proto); // holy closure!
}
for (var e in ext) {
if (!ext.hasOwnProperty(e)) {
continue; // a bit ugly imo, but it helps to prevent the indentation
// from blowing up
}
// this needs some refactoring, it creates bound and unbound
var val = ext[e], func = is('Function', val);
if (/^\$/.test(e)) { // statics
proto[e] = copy(val);
clas[e] = clas.prototype[e] = func ? wrap(clas, val) : val;
} else if (func) {
clas[e] = wrap(proto[e] = clas.prototype[e] = val);
}
}
return clas;
};
// this could also need some clean up I suppose
for (var i = ctor.hasOwnProperty('init') ? 0 : 1,
l = arguments.length; i < l; i++) {
var arg = arguments[i];
is('Object', arg) ? clas.extend(arg) : arg.extend(clas);
}
return clas;
}