src/basis.js
function createClass(SuperClass){
      var classId = classSeed++;

      if (typeof SuperClass != 'function')
        SuperClass = BaseClass;

      /** @cut */ var className = '';

      /** @cut */ for (var i = 1, extension; extension = arguments[i]; i++)
      /** @cut */   if (typeof extension != 'function' && extension.className)
      /** @cut */     className = extension.className;

      /** @cut */ if (!className)
      /** @cut */   className = SuperClass.className + '._Class' + classId;

      // temp class constructor with no init call
      var NewClassProto = function(){};

      // verbose name in dev
      /** @cut */ NewClassProto = devVerboseName(className, {}, NewClassProto);

      NewClassProto.prototype = SuperClass.prototype;

      var newProto = new NewClassProto;
      var newClassProps = {
        /** @cut */ className: className,

        basisClassId_: classId,
        superClass_: SuperClass,
        extendConstructor_: !!SuperClass.extendConstructor_,

        // class methods
        isSubclassOf: isSubclassOf,
        subclass: function(){
          return createClass.apply(null, [NewClass].concat(arrayFrom(arguments)));
        },
        extend: extendClass,
        factory: function(config){
          return factory(function(extra){
            return new NewClass(merge(config, extra));
          });
        },

        // auto extend creates a subclass
        __extend__: function(value){
          if (value && value !== SELF && (typeof value == 'object' || (typeof value == 'function' && !isClass(value))))
            return BaseClass.create.call(null, NewClass, value);
          else
            return value;
        },

        // new class prototype
        prototype: newProto
      };

      // extend NewClass prototype
      for (var i = 1, extension; extension = arguments[i]; i++)
        newClassProps.extend(extension);

      /** @cut */if (newProto.init !== BaseClass.prototype.init && !/^function[^(]*\(\)/.test(newProto.init) && newClassProps.extendConstructor_) consoleMethods.warn('probably wrong extendConstructor_ value for ' + newClassProps.className);

      // new class constructor
      var NewClass = newClassProps.extendConstructor_
        // constructor with instance extension
        ? function(extend){
            // mark object
            this.basisObjectId = instanceSeed.id++;

            // extend and override instance properties
            var prop;
            for (var key in extend)
            {
              prop = this[key];
              this[key] = prop && prop.__extend__
                ? prop.__extend__(extend[key])
                : extend[key];
            }

            // call constructor
            this.init();

            // post init
            this.postInit();
          }

        // simple constructor
        : function(){
            // mark object
            this.basisObjectId = instanceSeed.id++;

            // call constructor
            this.init.apply(this, arguments);

            // post init
            this.postInit();
          };

      // verbose name in dev
      // NOTE: this code makes Chrome and Firefox show class name in console
      /** @cut */ NewClass = devVerboseName(className, { instanceSeed: instanceSeed }, NewClass);

      // add constructor property to prototype
      newProto.constructor = NewClass;

      for (var key in newProto)
        if (newProto[key] === SELF)
          newProto[key] = NewClass;
        //else
        //  newProto[key] = newProto[key];

      // extend constructor with properties
      extend(NewClass, newClassProps);

      // for class introspection
      /** @cut */ classes.push(NewClass);

      // return new class
      return NewClass;
    }
function createClass(SuperClass){
      var classId = classSeed++;

      if (typeof SuperClass != 'function')
        SuperClass = BaseClass;

      /** @cut */ var className = '';

      /** @cut */ for (var i = 1, extension; extension = arguments[i]; i++)
      /** @cut */   if (typeof extension != 'function' && extension.className)
      /** @cut */     className = extension.className;

      /** @cut */ if (!className)
      /** @cut */   className = SuperClass.className + '._Class' + classId;

      // temp class constructor with no init call
      var NewClassProto = function(){};

      // verbose name in dev
      /** @cut */ NewClassProto = devVerboseName(className, {}, NewClassProto);

      NewClassProto.prototype = SuperClass.prototype;

      var newProto = new NewClassProto;
      var newClassProps = {
        /** @cut */ className: className,

        basisClassId_: classId,
        superClass_: SuperClass,
        extendConstructor_: !!SuperClass.extendConstructor_,

        // class methods
        isSubclassOf: isSubclassOf,
        subclass: function(){
          return createClass.apply(null, [NewClass].concat(arrayFrom(arguments)));
        },
        extend: extendClass,
        factory: function(config){
          return factory(function(extra){
            return new NewClass(merge(config, extra));
          });
        },

        // auto extend creates a subclass
        __extend__: function(value){
          if (value && value !== SELF && (typeof value == 'object' || (typeof value == 'function' && !isClass(value))))
            return BaseClass.create.call(null, NewClass, value);
          else
            return value;
        },

        // new class prototype
        prototype: newProto
      };

      // extend NewClass prototype
      for (var i = 1, extension; extension = arguments[i]; i++)
        newClassProps.extend(extension);

      /** @cut */if (newProto.init !== BaseClass.prototype.init && !/^function[^(]*\(\)/.test(newProto.init) && newClassProps.extendConstructor_) consoleMethods.warn('probably wrong extendConstructor_ value for ' + newClassProps.className);

      // new class constructor
      var NewClass = newClassProps.extendConstructor_
        // constructor with instance extension
        ? function(extend){
            // mark object
            this.basisObjectId = instanceSeed.id++;

            // extend and override instance properties
            var prop;
            for (var key in extend)
            {
              prop = this[key];
              this[key] = prop && prop.__extend__
                ? prop.__extend__(extend[key])
                : extend[key];
            }

            // call constructor
            this.init();

            // post init
            this.postInit();
          }

        // simple constructor
        : function(){
            // mark object
            this.basisObjectId = instanceSeed.id++;

            // call constructor
            this.init.apply(this, arguments);

            // post init
            this.postInit();
          };

      // verbose name in dev
      // NOTE: this code makes Chrome and Firefox show class name in console
      /** @cut */ NewClass = devVerboseName(className, { instanceSeed: instanceSeed }, NewClass);

      // add constructor property to prototype
      newProto.constructor = NewClass;

      for (var key in newProto)
        if (newProto[key] === SELF)
          newProto[key] = NewClass;
        //else
        //  newProto[key] = newProto[key];

      // extend constructor with properties
      extend(NewClass, newClassProps);

      // for class introspection
      /** @cut */ classes.push(NewClass);

      // return new class
      return NewClass;
    }
function createClass ( SuperClass ) { var classId = classSeed ++ ; if ( typeof SuperClass != 'function' ) SuperClass = BaseClass ; /** @cut */ var className = '' ; /** @cut */ for ( var i = 1 , extension ; extension = arguments [ i ] ; i ++ ) /** @cut */ if ( typeof extension != 'function' && extension . className ) /** @cut */ className = extension . className ; /** @cut */ if ( ! className ) /** @cut */ className = SuperClass . className + '._Class' + classId ; // temp class constructor with no init call var NewClassProto = function ( ) { } ; // verbose name in dev /** @cut */ NewClassProto = devVerboseName ( className , { } , NewClassProto ) ; NewClassProto . prototype = SuperClass . prototype ; var newProto = new NewClassProto ; var newClassProps = { /** @cut */ className : className , basisClassId_ : classId , superClass_ : SuperClass , extendConstructor_ : ! ! SuperClass . extendConstructor_ , // class methods isSubclassOf : isSubclassOf , subclass : function ( ) { return createClass . apply ( null , [ NewClass ] . concat ( arrayFrom ( arguments ) ) ) ; } , extend : extendClass , factory : function ( config ) { return factory ( function ( extra ) { return new NewClass ( merge ( config , extra ) ) ; } ) ; } , // auto extend creates a subclass __extend__ : function ( value ) { if ( value && value !== SELF && ( typeof value == 'object' || ( typeof value == 'function' && ! isClass ( value ) ) ) ) return BaseClass . create . call ( null , NewClass , value ) ; else return value ; } , // new class prototype prototype : newProto } ; // extend NewClass prototype for ( var i = 1 , extension ; extension = arguments [ i ] ; i ++ ) newClassProps . extend ( extension ) ; /** @cut */ if ( newProto . init !== BaseClass . prototype . init && ! / ^function[^(]*\(\) / . test ( newProto . init ) && newClassProps . extendConstructor_ ) consoleMethods . warn ( 'probably wrong extendConstructor_ value for ' + newClassProps . className ) ; // new class constructor var NewClass = newClassProps . extendConstructor_ // constructor with instance extension ? function ( extend ) { // mark object this . basisObjectId = instanceSeed . id ++ ; // extend and override instance properties var prop ; for ( var key in extend ) { prop = this [ key ] ; this [ key ] = prop && prop . __extend__ ? prop . __extend__ ( extend [ key ] ) : extend [ key ] ; } // call constructor this . init ( ) ; // post init this . postInit ( ) ; } // simple constructor : function ( ) { // mark object this . basisObjectId = instanceSeed . id ++ ; // call constructor this . init . apply ( this , arguments ) ; // post init this . postInit ( ) ; } ; // verbose name in dev // NOTE: this code makes Chrome and Firefox show class name in console /** @cut */ NewClass = devVerboseName ( className , { instanceSeed : instanceSeed } , NewClass ) ; // add constructor property to prototype newProto . constructor = NewClass ; for ( var key in newProto ) if ( newProto [ key ] === SELF ) newProto [ key ] = NewClass ; //else //  newProto[key] = newProto[key]; // extend constructor with properties extend ( NewClass , newClassProps ) ; // for class introspection /** @cut */ classes . push ( NewClass ) ; // return new class return NewClass ; }
Class constructor.
@param {function()} SuperClass Class that new one inherits of.
@param {...(object|function())} extensions Objects that extends new class prototype.
@return {function()} A new class.
Class constructor .