octavian-nita
12/25/2013 - 7:40 PM

JavaScript utilities

JavaScript utilities

// leading semicolon prevents the IIFE from being passed as argument to concatenated code
// (see https://blog.mariusschulz.com/2016/01/13/disassembling-javascripts-iife-syntax)
;(function() {
  'use strict';

  if (typeof extend !== 'function') {
    function extend(target /*, ...sources */) {
      if (arguments.length <= 1) { return target; }
      if (!target) { target = {}; }

      var i, sl, j, kl, source, keys;
      for (i = 1, sl = arguments.length; i < sl; i++) {
        if (typeof (source = arguments[i]) === 'object') {
          for (j = 0, kl = (keys = Object.keys(source)).length; j < kl; j++) { target[keys[j]] = source[keys[j]]; }
        }
      }

      return target;
    }
  }

  if (typeof Array.prototype.shuffle !== 'function') {
    /**
     * Shuffles the values in <code>this</code> {Array} using a version of the Fisher–Yates algorithm.
     */
    Array.prototype.shuffle = function() {
      var i = this.length, j, tmp;
      while (--i > 0) {
        j = Math.floor(Math.random() * (i + 1));
        tmp = this[i];
        this[i] = this[j];
        this[j] = tmp;
      }
      return this;
    };
  }

  if (typeof Object.create !== 'function') {
    /**
     * <p>
     * Polyfill for
     * <a href="http://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/create">
     *   Object.create()
     * </a> that supports a second argument.
     * </p>
     * <p>
     * Usage example to achieve <em>classical</em> inheritance with <code>Object.create()</code>:
     * <pre><code>
     *  function Base() { ... }
     *  Base.prototype.foo = function () { ... }
     *
     *  function Derived(...) {
     *    if (!(this instanceof Derived)) { return new Derived(...); }
     *    Base.apply(this, arguments);
     *    // own initialization...
     *  }
     *
     *  Derived.prototype = Object.create(Base.prototype);
     *  Derived.prototype.constructor = Derived;
     *
     *  // Optional, extra goodies
     *  Derived.prototype.super = Base.prototype;
     * </code></pre>
     * </p>
     *
     * @see https://gist.github.com/roboticstone/bf537252607286aa8ef6
     */
    Object.create = function(proto, props) {
      var t = typeof proto, prop, result;
      if (t !== 'object' && t !== 'function') {
        throw TypeError('Argument must be an object or a function');
      }

      function Ctor() {};
      Ctor.prototype = proto;
      result = new Ctor();
      Ctor.prototype = null;

      // Copy the enumerable properties of second parameter into the new object:
      t = typeof props;
      if (t === 'object' || t === 'function') {
        for (prop in props) {
          if (props.hasOwnProperty((prop))) {
            result[prop] = props[prop].value;
          }
        }
      }

      return result;
    };
  }
}());