classes.js
function (constructor, prototypes, chainConstruct) {

        var instance = this,
            constructorClosure = {},
            baseProt, proto, constrFn;
        if (typeof constructor === 'boolean') {
            constructor = null;
            prototypes = null;
            chainConstruct = constructor;
        }

        else {
            if ((typeof constructor === 'object') && (constructor!==null)) {
                chainConstruct = prototypes;
                prototypes = constructor;
                constructor = null;
            }

            if (typeof prototypes === 'boolean') {
                chainConstruct = prototypes;
                prototypes = null;
            }
        }

        (typeof chainConstruct === 'boolean') || (chainConstruct=DEFAULT_CHAIN_CONSTRUCT);

        constrFn = constructor || NOOP;
        constructor = function() {
            constructorClosure.constructor.$$constrFn.apply(this, arguments);
        };

        constructor = (function(originalConstructor) {
            return function() {
                var context = this;
                if (constructorClosure.constructor.$$chainConstructed) {
                    context.__classCarier__ = constructorClosure.constructor.$$super.constructor;
                    context.__origProp__ = 'constructor';
                    context.__classCarier__.apply(context, arguments);
                    context.$origMethods = constructorClosure.constructor.$$orig.constructor;
                }
                context.__classCarier__ = constructorClosure.constructor;
                context.__origProp__ = 'constructor';
                originalConstructor.apply(context, arguments);
                // only call aferInit on the last constructor of the chain:
                (constructorClosure.constructor===context.constructor) && context.afterInit();
            };
        })(constructor);

        baseProt = instance.prototype;
        proto = Object.create(baseProt);
        constructor.prototype = proto;

        // webkit doesn't let all objects to have their constructor redefined
        // when directly assigned. Using `defineProperty will work:
        Object.defineProperty(proto, 'constructor', {value: constructor});

        constructor.$$chainConstructed = chainConstruct ? true : false;
        constructor.$$super = baseProt;
        constructor.$$orig = {
            constructor: constructor
        };
        constructor.$$constrFn = constrFn;
        constructorClosure.constructor = constructor;
        prototypes && constructor.mergePrototypes(prototypes, true);
        return constructor;
    }
function (constructor, prototypes, chainConstruct) {

        var instance = this,
            constructorClosure = {},
            baseProt, proto, constrFn;
        if (typeof constructor === 'boolean') {
            constructor = null;
            prototypes = null;
            chainConstruct = constructor;
        }

        else {
            if ((typeof constructor === 'object') && (constructor!==null)) {
                chainConstruct = prototypes;
                prototypes = constructor;
                constructor = null;
            }

            if (typeof prototypes === 'boolean') {
                chainConstruct = prototypes;
                prototypes = null;
            }
        }

        (typeof chainConstruct === 'boolean') || (chainConstruct=DEFAULT_CHAIN_CONSTRUCT);

        constrFn = constructor || NOOP;
        constructor = function() {
            constructorClosure.constructor.$$constrFn.apply(this, arguments);
        };

        constructor = (function(originalConstructor) {
            return function() {
                var context = this;
                if (constructorClosure.constructor.$$chainConstructed) {
                    context.__classCarier__ = constructorClosure.constructor.$$super.constructor;
                    context.__origProp__ = 'constructor';
                    context.__classCarier__.apply(context, arguments);
                    context.$origMethods = constructorClosure.constructor.$$orig.constructor;
                }
                context.__classCarier__ = constructorClosure.constructor;
                context.__origProp__ = 'constructor';
                originalConstructor.apply(context, arguments);
                // only call aferInit on the last constructor of the chain:
                (constructorClosure.constructor===context.constructor) && context.afterInit();
            };
        })(constructor);

        baseProt = instance.prototype;
        proto = Object.create(baseProt);
        constructor.prototype = proto;

        // webkit doesn't let all objects to have their constructor redefined
        // when directly assigned. Using `defineProperty will work:
        Object.defineProperty(proto, 'constructor', {value: constructor});

        constructor.$$chainConstructed = chainConstruct ? true : false;
        constructor.$$super = baseProt;
        constructor.$$orig = {
            constructor: constructor
        };
        constructor.$$constrFn = constrFn;
        constructorClosure.constructor = constructor;
        prototypes && constructor.mergePrototypes(prototypes, true);
        return constructor;
    }
function ( constructor , prototypes , chainConstruct ) { var instance = this , constructorClosure = { } , baseProt , proto , constrFn ; if ( typeof constructor === 'boolean' ) { constructor = null ; prototypes = null ; chainConstruct = constructor ; } else { if ( ( typeof constructor === 'object' ) && ( constructor !== null ) ) { chainConstruct = prototypes ; prototypes = constructor ; constructor = null ; } if ( typeof prototypes === 'boolean' ) { chainConstruct = prototypes ; prototypes = null ; } } ( typeof chainConstruct === 'boolean' ) || ( chainConstruct = DEFAULT_CHAIN_CONSTRUCT ) ; constrFn = constructor || NOOP ; constructor = function ( ) { constructorClosure . constructor . $$constrFn . apply ( this , arguments ) ; } ; constructor = ( function ( originalConstructor ) { return function ( ) { var context = this ; if ( constructorClosure . constructor . $$chainConstructed ) { context . __classCarier__ = constructorClosure . constructor . $$super . constructor ; context . __origProp__ = 'constructor' ; context . __classCarier__ . apply ( context , arguments ) ; context . $origMethods = constructorClosure . constructor . $$orig . constructor ; } context . __classCarier__ = constructorClosure . constructor ; context . __origProp__ = 'constructor' ; originalConstructor . apply ( context , arguments ) ; // only call aferInit on the last constructor of the chain: ( constructorClosure . constructor === context . constructor ) && context . afterInit ( ) ; } ; } ) ( constructor ) ; baseProt = instance . prototype ; proto = Object . create ( baseProt ) ; constructor . prototype = proto ; // webkit doesn't let all objects to have their constructor redefined // when directly assigned. Using `defineProperty will work: Object . defineProperty ( proto , 'constructor' , { value : constructor } ) ; constructor . $$chainConstructed = chainConstruct ? true : false ; constructor . $$super = baseProt ; constructor . $$orig = { constructor : constructor } ; constructor . $$constrFn = constrFn ; constructorClosure . constructor = constructor ; prototypes && constructor . mergePrototypes ( prototypes , true ) ; return constructor ; }
Returns a newly created class inheriting from this class
using the given `constructor` with the
prototypes listed in `prototypes` merged in.


The newly created class has the `$$super` static property
available to access all of is ancestor's instance methods.

Further methods can be added via the [mergePrototypes](#method_mergePrototypes).

@example

var Circle = Shape.subClass(
function (x, y, r) {
// arguments will automaticly be passed through to Shape's constructor
this.r = r;
},
{
area: function () {
return this.r * this.r * Math.PI;
}
}
);

@method subClass
@param [constructor] {Function} The function that will serve as constructor for the new class.
If `undefined` defaults to `NOOP`
@param [prototypes] {Object} Hash map of properties to be added to the prototype of the new class.
@param [chainConstruct=true] {Boolean} Whether -during instance creation- to automaticly construct in the complete hierarchy with the given constructor arguments.
@return the new class.
Returns a newly created class inheriting from this class using the given constructor with the prototypes listed in prototypes merged in .