JSFiddle - React, Tailwind, and code Playground

by Alexander

JavaScript

console.clear();
/**
 * Синтаксис:
 * Class.extend(props)
 * Class.extend(props, staticProps)
 * Class.extend([mixins], props)
 * Class.extend([mixins], props, staticProps)
*/
!function(window) {
  window.Class = function() { /* вся магия - в Class.extend */  };

  Class.extend = function(props, staticProps) {

    var mixins = [];

    // если первый аргумент -- массив, то переназначить аргументы    
    if ({}.toString.apply(arguments[0]) == "[object Array]") {
      mixins = arguments[0];
      props = arguments[1];
      staticProps = arguments[2];
    }

    // эта функция будет возвращена как результат работы extend
    function Constructor() {
      this.init && this.init.apply(this, arguments);
    }

    // this -- это класс "перед точкой", для которого вызван extend (Animal.extend)
    // наследуем от него:
    Constructor.prototype = Class.inherit(this.prototype);

    // constructor был затёрт вызовом inherit
    Constructor.prototype.constructor = Constructor;

    // добавим возможность наследовать дальше
    Constructor.extend = Class.extend;

    // скопировать в Constructor статические свойства
    copyWrappedProps(staticProps, Constructor, this);

    // скопировать в Constructor.prototype свойства из примесей и props
    for (var i = 0; i < mixins.length; i++) {
      copyWrappedProps(mixins[i], Constructor.prototype, this.prototype);
    }
    copyWrappedProps(props, Constructor.prototype, this.prototype);

    return Constructor;
  };


  //---------- вспомогательные методы ----------

  // fnTest -- регулярное выражение, 
  // которое проверяет функцию на то, есть ли в её коде вызов _super
  // 
  // для его объявления мы проверяем, поддерживает ли функция преобразование
  // в код вызовом toString: /xyz/.test(function() {xyz})
  // в редких мобильных браузерах -- не поддерживает, поэтому регэксп будет /./
  var fnTest = /xyz/.test(function() {xyz}) ? /\b_super\b/ : /./;


  // копирует свойства из props в targetPropsObj
  // третий аргумент...