I needed JavaScript inheritance that offered calling of overridden methods (super calls).Furthermore I needed a possibiliy to add behaviour to instances (mixins). Mixins should not only be full classes including mentioned inheritance but also be able to override its instance' method.Below is what I came up with. It does what I needed it to do. May I ask to have a look at the implementation and its possible shortcomings?log = function( s ) {var dn = document.getElementById( output );dn.innerHTML = dn.innerHTML + </br> + s;}function Class() { }Class.prototype.construct = function() {};Class.create = function() {// create new instancevar oClass = arguments[0];var args = arguments[1];var oInstance = new oClass( args ); // in case of mixins add behaviour to instanceif( args && args.mixins ) { var c = args.mixins.length; // loop through mixins prototypes an attach for( var ix=0; ix<c; ix++ ) {  var oMixin = args.mixins[ ix ].o.prototype;  // set flag whether mixin has init function  var bInit = false;  for (var sMember in oMixin) {   if( sMember == _init ) {    // mixin has init fuction    bInit = true;   }   else {    var oMember = oMixin[sMember];                          if (oMember instanceof Function &&         oInstance[sMember] ) {     // in case of overrides save mixee's orig      // method and add _mixee() to call it     if( ! oInstance.lfnMixee ) {      oInstance.lfnMixee = {};      oInstance._mixee = function() {       var that = arguments[0];       var args = arguments[1];       var sfn = arguments[2];       return that.lfnMixee[ sfn ].apply( that, args );      };     }     var fn = oInstance[ sMember ];     oInstance.lfnMixee[sMember] = fn;    }    // augment mixin's members    oInstance[ sMember ] = oMember;   }  }  if( bInit ) {   // call mixin's init function with passed on arguments   var aConfig = args.mixins[ ix ].aConfig;   oMixin._init.apply( oInstance, [ aConfig ] );  } }}if( oInstance._init ) { // call init function if exists oInstance._init( args );}return oInstance;};Class.extend = function(o) {var oNew = function() { if (arguments[ 0 ] !== Class) {  // call constructor if not base   this.construct.apply( this, arguments );  }};// get prototype and hook to parentvar oPrototype = new this(Class);var oParent = this.prototype;for (var sMember in o) { var oMember = o[sMember];                       if (oMember instanceof Function) {  oMember.oParent = oParent;  // in case we override add method  // _parent() to call parent's function  oPrototype._parent = function() {   var that = arguments[0];   var args = arguments[1];   var sfn = arguments[2];   return args.callee.oParent[ sfn ].apply( that, args )  }; }// augment with membersoPrototype[sMember] = oMember;}// set prototypeoNew.prototype = oPrototype;// and make it extendableoNew.extend = this.extend;      return oNew;};/* ****** TEST CODE ********* */var Person = Class.extend({name : null,_init : function( a ) { this.name = a.name;},say : function( s ) { s = '('+this.name+') ' + s +''; log( s );} });var Moderator = Person.extend({_init : function( a ) { this._parent( this, arguments, '_init' ); this.name = [mod| + this.name +];},say : function( s ) { log( 'as moderator I say: ' ); this._parent( this, arguments, 'say' );},read : function( s ) { s = ...+s; log( s );} });var Megaphone = Class.extend({say : function( s ) { log( &lt;YELL&gt; ); this._mixee( this, arguments, 'say' ); log( &lt;/YELL&gt; );}});var Googles = Class.extend({type : Googles,color : transparent,read : function() { log( &lt;SHARP&gt; ); this._mixee( this, arguments, 'read' ); log( &lt;/SHARP&gt; );},clean : function(){ log( this.name +  cleaning + this.color +  + this.type );} });var Shades = Googles.extend({type : Shades,_init : function( a ) { this.color = a.color;},read : function() { log( &lt;+this.color+&gt; ); this._parent( this, arguments, 'read' ); log( &lt;/+this.color+&gt; );},clean : function(){ this._parent( this, arguments, 'clean' );} });var john = Class.create( Person, {name : john,mixins: [ { o : Googles} ] } );var joseph = Class.create( Moderator, { name : joseph,mixins: [ { o : Shades, aConfig : { color : blue } } , { o : Megaphone }] } );john.say( 'hello' );john.clean();log( '---------' );joseph.say( 'hello' );joseph.read( 'agenda of meeting' );joseph.clean();<div id=output></div>
JavaScript inheritance with super calls and mixins
javascript;inheritance;mixins