src/helpers.js
function cloner(deep, item) {
  if (!item ||
      typeof item !== 'object' ||
      item instanceof Error ||
      item instanceof MonkeyDefinition ||
      item instanceof Monkey ||
      ('ArrayBuffer' in global && item instanceof ArrayBuffer))
    return item;

  // Array
  if (type.array(item)) {
    if (deep) {
      const a = new Array(item.length);

      for (let i = 0, l = item.length; i < l; i++)
        a[i] = cloner(true, item[i]);
      return a;
    }

    return slice(item);
  }

  // Date
  if (item instanceof Date)
    return new Date(item.getTime());

  // RegExp
  if (item instanceof RegExp)
    return cloneRegexp(item);

  // Object
  if (type.object(item)) {
    const o = {};

    // NOTE: could be possible to erase computed properties through `null`.
    const props = Object.getOwnPropertyNames(item);
    for (let i = 0, l = props.length; i < l; i++) {
      const name = props[i];
      const k = Object.getOwnPropertyDescriptor(item, name);
      if (k.enumerable === true) {
        if (k.get && k.get.isLazyGetter) {
          Object.defineProperty(o, name, {
            get: k.get,
            enumerable: true,
            configurable: true
          });
        }
        else {
          o[name] = deep ? cloner(true, item[name]) : item[name];
        }
      }
      else if (k.enumerable === false) {
        Object.defineProperty(o, name, {
          value: deep ? cloner(true, k.value) : k.value,
          enumerable: false,
          writable: true,
          configurable: true
        });
      }
    }
    return o;
  }

  return item;
}
function cloner(deep, item) {
  if (!item ||
      typeof item !== 'object' ||
      item instanceof Error ||
      item instanceof MonkeyDefinition ||
      item instanceof Monkey ||
      ('ArrayBuffer' in global && item instanceof ArrayBuffer))
    return item;

  // Array
  if (type.array(item)) {
    if (deep) {
      const a = new Array(item.length);

      for (let i = 0, l = item.length; i < l; i++)
        a[i] = cloner(true, item[i]);
      return a;
    }

    return slice(item);
  }

  // Date
  if (item instanceof Date)
    return new Date(item.getTime());

  // RegExp
  if (item instanceof RegExp)
    return cloneRegexp(item);

  // Object
  if (type.object(item)) {
    const o = {};

    // NOTE: could be possible to erase computed properties through `null`.
    const props = Object.getOwnPropertyNames(item);
    for (let i = 0, l = props.length; i < l; i++) {
      const name = props[i];
      const k = Object.getOwnPropertyDescriptor(item, name);
      if (k.enumerable === true) {
        if (k.get && k.get.isLazyGetter) {
          Object.defineProperty(o, name, {
            get: k.get,
            enumerable: true,
            configurable: true
          });
        }
        else {
          o[name] = deep ? cloner(true, item[name]) : item[name];
        }
      }
      else if (k.enumerable === false) {
        Object.defineProperty(o, name, {
          value: deep ? cloner(true, k.value) : k.value,
          enumerable: false,
          writable: true,
          configurable: true
        });
      }
    }
    return o;
  }

  return item;
}
function cloner ( deep , item ) { if ( ! item || typeof item !== 'object' || item instanceof Error || item instanceof MonkeyDefinition || item instanceof Monkey || ( 'ArrayBuffer' in global && item instanceof ArrayBuffer ) ) return item ; // Array if ( type . array ( item ) ) { if ( deep ) { const a = new Array ( item . length ) ; for ( let i = 0 , l = item . length ; i < l ; i ++ ) a [ i ] = cloner ( true , item [ i ] ) ; return a ; } return slice ( item ) ; } // Date if ( item instanceof Date ) return new Date ( item . getTime ( ) ) ; // RegExp if ( item instanceof RegExp ) return cloneRegexp ( item ) ; // Object if ( type . object ( item ) ) { const o = { } ; // NOTE: could be possible to erase computed properties through `null`. const props = Object . getOwnPropertyNames ( item ) ; for ( let i = 0 , l = props . length ; i < l ; i ++ ) { const name = props [ i ] ; const k = Object . getOwnPropertyDescriptor ( item , name ) ; if ( k . enumerable === true ) { if ( k . get && k . get . isLazyGetter ) { Object . defineProperty ( o , name , { get : k . get , enumerable : true , configurable : true } ) ; } else { o [ name ] = deep ? cloner ( true , item [ name ] ) : item [ name ] ; } } else if ( k . enumerable === false ) { Object . defineProperty ( o , name , { value : deep ? cloner ( true , k . value ) : k . value , enumerable : false , writable : true , configurable : true } ) ; } } return o ; } return item ; }
Function cloning the given variable.

@todo: implement a faster way to clone an array.

@param  {boolean} deep - Should we deep clone the variable.
@param  {mixed}   item - The variable to clone
@return {mixed}        - The cloned variable.
Function cloning the given variable .