函数柯里化

function currying (fn, args) {
  let len = fn.length;
  args = args || [];
  return function () {
    const newArray = args.concat(Array.prototype.slice.call(arguments));

    if (newArray.length < len) {
      return currying.apply(this, fn, newArray);
    } else {
      return fn.apply(this, newArray);
    }
  }
}
function curry (fn, currArgs) {
    return function() {
        let args = [].slice.call(arguments);

        // 首次调用时,若未提供最后一个参数currArgs,则不用进行args的拼接
        if (currArgs !== undefined) {
            args = args.concat(currArgs);
        }

        // 递归调用
        if (args.length < fn.length) {
            return curry(fn, args);
        }

        // 递归出口
        return fn.apply(null, args);
    }
}
function curring (fn, ...rest1) {
  return function (...rest2) {
    return fn.apply(null, rest1.concat(rest2));
  }
}

function curringHelper (fn, len) {
  let leng = len || fn.length;
  return function (...rest) {
    return leng >= rest 
      ? fn.apply(this, rest) 
      : curringHelper(curring.apply(this, [fn].concat(rest)), leng - rest.length);
  }
}