什么是柯里化

先用一个简单的例子来引出

var add=function(a,b,c){
    return a+b+c;
}

需要写一个函数,满足curry(add)(1)(2)(3)输出结果为6
由此可以看出curry 函数的功能:每传递一个参数调用函数,就返回一个新函数处理剩余的参数

柯里的实现

var curry = function(fn){
    if(typeof fn!=='function'){
        throw Error('No function provided');
    }

    var slice = [].slice;
    return function curriedFn(){
      var args = slice.call(arguments);
      if(args.length < fn.length){
        return function() {
            return curriedFn.apply(this, args.concat(slice.call(arguments)));
        }
      }

      return fn.apply(null, args);
    };
};
curry(add)(100)(200)(300)
  1. 首先调用curry(add),会返回一个闭包函数curriedFn
    这个函数记住了add所需要的参数个数fn.length
  2. 继续执行curriedFn(100),该函数会判断当前参数个数是否达到了add所需要的参数个数
  3. 此时args.length是1,并未达到add函数所需要的3个,就继续返回一个带有参数100的,并且会合并新参数的闭包
  4. 这里用args.concat(slice.call(arguments))来合并, 这里用slice.call(arguments)把arguments转成真正的数组

    如果对这点不理解可以参考 STACKOVERFLOW

  5. 以此往后,当达到参数个数时,才会去用合并出来的arguments去执行add