Skip to content

Instantly share code, notes, and snippets.

@mikewilcox
Created January 25, 2013 03:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikewilcox/4631595 to your computer and use it in GitHub Desktop.
Save mikewilcox/4631595 to your computer and use it in GitHub Desktop.
Testing an inheritance system
var declare = function(){
var
args = Array.prototype.slice.call(arguments)
constructors = [],
protos = [];
for(var i = 0; i < args.length; i++){
if( typeof args[i] === 'function'){
console.log(' fn', args[i].prototype.constructor);
constructors.push(args[i]);
protos.push(args[i].prototype);
}else if( typeof args[i] === 'object'){
if(args[i].constructor){
constructors.push(args[i].constructor);
delete args[i].constructor;
}
protos.push(args[i]); // check for constructor()
}
}
console.log('constructors');
var Constructor = function(){
// loop through constructors
for(var i = 0; i < constructors.length; i++){
constructors[i].apply(this, arguments);
}
if(this.postscript) this.postscript.apply(this, arguments);
};
var count = 0;
var nom = 1;
var mix = function(o1, o2){
for(var key in o2){
if(o2.hasOwnProperty(key)){
if(o1[key]){
(function(){
var tmp1 = o1[key];
console.log('inherit -> ', !!tmp1.super);
o1[key] = o2[key];
o1[key].super = function(self, args){
if(count++ > 4) return;
//tmp1.apply(self, [args]);
console.log(' super', tmp1.nom, 'from', o1[key].nom);
Constructor.prototype._inherited(tmp1, self, args);
}
})();
}else{
o1[key] = o2[key];
}
o1[key].nom = 'NOM' + nom++;
}
}
};
var chain = function(proto, props){
var F = function(){}
F.prototype = proto;
var instance = new F();
if(props){
mix(instance, props);
}
return instance;
};
var o;
for(var i = 0; i < protos.length; i++){
o = chain(o, protos[i]);
}
Constructor.prototype = o;
Constructor.prototype._inherited = function(fn, self, args){
console.log('inherit', args, this, self);
fn.call(self, args);
}
Constructor.constructor = args[args.length-1];
return Constructor;
};
var testMulti = function(){
var A = function(id){
this.id = id || 'unset';
console.log('A', this.id);
};
A.prototype = {
foo: function(){
console.log('foo', this.id);
},
bar: function(){
console.log('bar', this.id);
}
};
var B = function(id){
this.id = id || 'unset';
console.log('B', this.id);
};
B.prototype = {
foo: function(){
console.log('foo', this.id);
},
boo: function(){
console.log('boo', this.id);
},
zap: function(){
console.log('zap', this.id);
}
};
var C = function(id){
this.id = id || 'unset';
console.log('C', this.id);
};
C.prototype = {
zip: function(){
console.log('zip', this.id);
},
bip: function(){
console.log('bip', this.id);
}
};
var F = declare(A,B,C, {
constructor: function(id){
this.id = id || 'unset';
console.log('F', this.id);
},
oop: function(){
console.log('oop', this.id);
}
});
var instance = new F('mike');
console.log(instance);
instance.foo();
instance.zap();
instance.bip();
instance.oop();
}
var testSingle = function(){
var O = declare({
constructor: function(id){
this.id = id || 'unset';
console.log('O', this.id);
},
oop: function(){
console.log('oop.' + this.id);
}
});
var o = new O('oOo');
console.log(o);
o.oop();
}
var testOverride = function(){
var p1 = {
constructor: function(id){
this.id = id || 'unset';
console.log('S1', this.id);
},
oop: function(a){
console.log('oop 1 ', this.id, a);
}
};
var p2 = {
constructor: function(id){
this.id = id || 'unset';
console.log('S2', this.id);
},
oop: function(a){
console.log('oop 2 ', this.id, a);
this.oop.super(this, a);
}
};
var p3 = {
constructor: function(id){
this.id = id || 'unset';
console.log('S3', this.id);
},
oop: function(a){
console.log('oop 3 ', this.id, a);
this.oop.super(this, a);
},
postscript: function(){
console.log('constructors finished!');
}
};
p1.oop.name = 'p1';
p2.oop.name = 'p2';
p3.oop.name = 'p3';
var Shadowed = declare(p1,p2,p3);
var s = new Shadowed('sss');
console.log(s);
console.log('name > ', p1.oop.nom, p2.oop.nom, p3.oop.nom);
console.log(p1.oop === p2.oop, p1.oop === s.oop, s.oop === p2.oop);
s.oop('mike');
//delete s.oop
//s.oop('');
}
testOverride();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment