函数式编程之一柯里化

什么是柯里化?

柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数的函数

下面来看一个案例,两值相加:

柯里化之前(常见用法)

function add(x, y) {
    return x + y
}
add(1, 2)

柯里化之后

function add(x) {
    return function(y) {
        return x + y
    }
}
add(1)(2)

从上面两个例子中似乎好像对柯里化有点感觉了,嗯,再想想

学习新概念时最怕的就是自己理解错了,这样的体验简直无比糟糕,so我们再来看一个案例

function multi(a) {
    return function(b) {
        return function(c) {
            return a * b * c;
        }
    }
}
multi(1)(2)(3)

按着对柯里化的理解,我写了这个案例,转念一想,这也是柯里化么? 那么多个return看着有点瘆人,难道是我理解错了么,还是方式用错了,好吧,继续挖掘

然后找了一个关于柯里化的面试题

实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) = 6
add(1, 2, 3)(4) = 10
add(1)(2)(3)(4)(5) = 15

实现方案:

var addFn = function () {
  var _args = [];
  return function () {
    if (arguments.length === 0) {
      return _args.reduce(function (a, b) {
        return a + b;
      });
    };
    [].push.apply(_args, [].slice.call(arguments));
    return arguments.callee;
  }
};    
var sum = addFn();
sum(1,2,3)(4);  
console.log(sum());   // 10 

知识点:

1。[].slice.call(arguments)

     在ES6以前,我们将一个伪数组转换为真正数组通常情况下都是使用[ ].slice.call()方法

2。[].push.apply(a, b)

     将b追加到a里面

运行过程:

--> [].slice.call(arguments)通过arguments得到一个数组

--> [].push.apply(_args, [].slice.call(arguments))将数组Push到_args里面

--> 再次调用时通过闭包保存了上一次返回的值

--> sum()最后运行时,arguments.length === 0,通过reduce方法求和

 从例子中发现:sum(1,2,3)(4)通过闭包的方式保存了得到的值,不是每次都参与计算得到结果,而是在最后通过sum()才实现求和,以此能看出它的一个特点:延迟计算

en....貌似要是面试遇到这种题也能写出个答案来了,但是了目前为止我还是无法学以致用,不明白这种函数适用于什么场景

原文地址:https://www.cnblogs.com/Tiboo/p/10633469.html