src/index.js
function Class(superCtor, props){
  let cls = function (...args) {
    if (!(this instanceof cls)) {
      throw new Error('Class constructors cannot be invoked without \'new\'');
    }
    //extend prototype data to instance
    //avoid instance change data to pullte prototype
    cls.extend(cls.__props__, this);
    if(isFunction(this.init)){
      this.__initReturn = this.init(...args);
    }
  };
  cls.__props__ = {};
  cls.extend = function(props, target){
    target = target || cls.prototype;
    let name, value;
    for(name in props){
      value = props[name];
      if (isArray(value)) {
        cls.__props__[name] = target[name] = extend([], value);
      }else if(isObject(value)){
        cls.__props__[name] = target[name] = extend({}, value);
      }else{
        target[name] = value;
      }
    }
    return cls;
  };
  cls.inherits = function(superCtor){
    cls.super_ = superCtor;
    //if superCtor.prototype is not enumerable
    if(Object.keys(superCtor.prototype).length === 0){
      cls.prototype = Object.create(superCtor.prototype, {
        constructor: {
          value: cls,
          enumerable: false,
          writable: true,
          configurable: true
        }
      });
    }else{
      extend(cls.prototype, superCtor.prototype);
    }
    return cls;
  };
  if (!isFunction(superCtor)) {
    props = superCtor;
  }else if (isFunction(superCtor)) {
    cls.inherits(superCtor);
  }
  if (props) {
    cls.extend(props);
  }
  /**
   * invoke super class method
   * @param  {String} name []
   * @param  {Mixed} data []
   * @return {Mixed}      []
   */
  cls.prototype.super = function(name, data){
    if (!this[name]) {
      this.super_c = null;
      return;
    }
    let super_ = this.super_c ? this.super_c.super_ : this.constructor.super_;
    if (!super_ || !isFunction(super_.prototype[name])) {
      this.super_c = null;
      return;
    }
    while(this[name] === super_.prototype[name] && super_.super_){
      super_ = super_.super_;
    }
    this.super_c = super_;
    if (!this.super_t) {
      this.super_t = 1;
    }
    if (!isArray(data) && !isArguments(data)) {
      data = arguments.length === 1 ? [] : [data];
    }
    let t = ++this.super_t, ret, method = super_.prototype[name];
    ret = method.apply(this, data);
    if (t === this.super_t) {
      this.super_c = null;
      this.super_t = 0;
    }
    return ret;
  };
  return cls;
}
function Class(superCtor, props){
  let cls = function (...args) {
    if (!(this instanceof cls)) {
      throw new Error('Class constructors cannot be invoked without \'new\'');
    }
    //extend prototype data to instance
    //avoid instance change data to pullte prototype
    cls.extend(cls.__props__, this);
    if(isFunction(this.init)){
      this.__initReturn = this.init(...args);
    }
  };
  cls.__props__ = {};
  cls.extend = function(props, target){
    target = target || cls.prototype;
    let name, value;
    for(name in props){
      value = props[name];
      if (isArray(value)) {
        cls.__props__[name] = target[name] = extend([], value);
      }else if(isObject(value)){
        cls.__props__[name] = target[name] = extend({}, value);
      }else{
        target[name] = value;
      }
    }
    return cls;
  };
  cls.inherits = function(superCtor){
    cls.super_ = superCtor;
    //if superCtor.prototype is not enumerable
    if(Object.keys(superCtor.prototype).length === 0){
      cls.prototype = Object.create(superCtor.prototype, {
        constructor: {
          value: cls,
          enumerable: false,
          writable: true,
          configurable: true
        }
      });
    }else{
      extend(cls.prototype, superCtor.prototype);
    }
    return cls;
  };
  if (!isFunction(superCtor)) {
    props = superCtor;
  }else if (isFunction(superCtor)) {
    cls.inherits(superCtor);
  }
  if (props) {
    cls.extend(props);
  }
  /**
   * invoke super class method
   * @param  {String} name []
   * @param  {Mixed} data []
   * @return {Mixed}      []
   */
  cls.prototype.super = function(name, data){
    if (!this[name]) {
      this.super_c = null;
      return;
    }
    let super_ = this.super_c ? this.super_c.super_ : this.constructor.super_;
    if (!super_ || !isFunction(super_.prototype[name])) {
      this.super_c = null;
      return;
    }
    while(this[name] === super_.prototype[name] && super_.super_){
      super_ = super_.super_;
    }
    this.super_c = super_;
    if (!this.super_t) {
      this.super_t = 1;
    }
    if (!isArray(data) && !isArguments(data)) {
      data = arguments.length === 1 ? [] : [data];
    }
    let t = ++this.super_t, ret, method = super_.prototype[name];
    ret = method.apply(this, data);
    if (t === this.super_t) {
      this.super_c = null;
      this.super_t = 0;
    }
    return ret;
  };
  return cls;
}
function Class ( superCtor , props ) { let cls = function ( ... args ) { if ( ! ( this instanceof cls ) ) { throw new Error ( 'Class constructors cannot be invoked without \'new\'' ) ; } //extend prototype data to instance //avoid instance change data to pullte prototype cls . extend ( cls . __props__ , this ) ; if ( isFunction ( this . init ) ) { this . __initReturn = this . init ( ... args ) ; } } ; cls . __props__ = { } ; cls . extend = function ( props , target ) { target = target || cls . prototype ; let name , value ; for ( name in props ) { value = props [ name ] ; if ( isArray ( value ) ) { cls . __props__ [ name ] = target [ name ] = extend ( [ ] , value ) ; } else if ( isObject ( value ) ) { cls . __props__ [ name ] = target [ name ] = extend ( { } , value ) ; } else { target [ name ] = value ; } } return cls ; } ; cls . inherits = function ( superCtor ) { cls . super_ = superCtor ; //if superCtor.prototype is not enumerable if ( Object . keys ( superCtor . prototype ) . length === 0 ) { cls . prototype = Object . create ( superCtor . prototype , { constructor : { value : cls , enumerable : false , writable : true , configurable : true } } ) ; } else { extend ( cls . prototype , superCtor . prototype ) ; } return cls ; } ; if ( ! isFunction ( superCtor ) ) { props = superCtor ; } else if ( isFunction ( superCtor ) ) { cls . inherits ( superCtor ) ; } if ( props ) { cls . extend ( props ) ; } /**
   * invoke super class method
   * @param  {String} name []
   * @param  {Mixed} data []
   * @return {Mixed}      []
   */ cls . prototype . super = function ( name , data ) { if ( ! this [ name ] ) { this . super_c = null ; return ; } let super_ = this . super_c ? this . super_c . super_ : this . constructor . super_ ; if ( ! super_ || ! isFunction ( super_ . prototype [ name ] ) ) { this . super_c = null ; return ; } while ( this [ name ] === super_ . prototype [ name ] && super_ . super_ ) { super_ = super_ . super_ ; } this . super_c = super_ ; if ( ! this . super_t ) { this . super_t = 1 ; } if ( ! isArray ( data ) && ! isArguments ( data ) ) { data = arguments . length === 1 ? [ ] : [ data ] ; } let t = ++ this . super_t , ret , method = super_ . prototype [ name ] ; ret = method . apply ( this , data ) ; if ( t === this . super_t ) { this . super_c = null ; this . super_t = 0 ; } return ret ; } ; return cls ; }
create Class in javascript
@param {Function} superCtor [super constructor]
@param {Object} props     []
create Class in javascript