Skip to content

Instantly share code, notes, and snippets.

@jsmaker
Created November 11, 2012 00:56
Show Gist options
  • Save jsmaker/4053198 to your computer and use it in GitHub Desktop.
Save jsmaker/4053198 to your computer and use it in GitHub Desktop.
BaseClass
function BaseClass(name, methods, statics){
var $$$ = 'function $$$(args) {'+
'args = arguments;'+
'if(!(this instanceof $$$)){ return new $$$($$$, arguments) }'+
'if(args[0] === $$$){ args = args[1] }'+
'if(this.init){ return this.init.apply(this, args) }'+
'}';
var _Class = ConstructorWithName(name);
_Class.classes = {};
_Class.classes[name] = _Class;
copy(_Class, methods, statics);
_Class.declare = function declare(name, methods, statics) {
'use strict';
var A = this;
var B = ConstructorWithName(name);
B.prototype = Object.create(A.prototype);
copy(B, methods, A);
copy(B, null, statics);
B.parentClass = A;
B.classes[name] = B;
B.prototype.constructor = B;
B.prototype._super = function (name) {
_super.call(this, A, name, arguments);
};
return B;
};
function _super(ParentClass, name, args) {
var value;
this._super_pos_ = this._super_pos_ ? this._super_pos_.parentClass : ParentClass;
if (this._super_pos_.prototype.hasOwnProperty(name)) {
value = this._super_pos_.prototype[name].apply(this, Array.prototype.slice.call(args, 1));
} else {
value = this._super.apply(this, args);
}
this._super_pos_ = null;
return value;
}
function ConstructorWithName(name){
var C = (new Function('return ' + $$$.split('$$$').join(name) ))();
if(!C.name){C.name=name}
return C;
}
function copy(_Class, methods, statics){
if (methods) { for (var p in methods) { _Class.prototype[p] = methods[p] } }
if (statics) { for (var s in statics) { if(statics.hasOwnProperty(s)){_Class[s] = statics[s]} } }
}
return _Class;
};
BaseClass.statics = {
instances:{}
};
BaseClass.methods = {
init: function() {
this.storeInstance();
},
log: function(args) {
args = Array.prototype.slice.call(arguments);
args.unshift('LOG:');
console && console.log.apply(console, args);
},
createInstance: function(name) {
var _Class = this.constructor.classes[name];
if (_Class) {
return new _Class(_Class, Array.prototype.slice.call(arguments, 1));
} else {
return null;
}
},
storeInstance: function(){
this.constructor.instances[this.constructor.name] = this.constructor.instances[this.constructor.name] || [];
this.constructor.instances[this.constructor.name].push(this);
},
removeStoredInstance: function(){
if(this.constructor.instances){
var i = this.constructor.instances[this.constructor.name].indexOf(this);
if (~i) {
this.constructor.instances[this.constructor.name].splice(i, 1);
}
}
},
destroy: function() {
this.removeStoredInstance();
},
test: function(v) {
this.log('Base', v);
}
};
var Base = BaseClass('Base', BaseClass.methods, BaseClass.statics);
var Low = Base.declare('Low', {
test: function(v) {
this.log('Low', v);
this._super('test', v + '!')
}
});
var Mid = Low.declare('Mid', {
test: function(v) {
this.log('Mid', v);
this._super('test', v + '!')
}
});
var High = Mid.declare('High', {
test: function(v) {
this.log('High', v);
this._super('test', v + '!')
}
});
var high = new High();
console.log(high);
console.log(Base.instances);
high.test('TEST');
high.destroy();
console.log(Base.instances);
console.log(Base.classes);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment