1. 程式人生 > >函數式編程之一柯裏化

函數式編程之一柯裏化

什麽 計算 func 這樣的 一個 這也 面試 color 之一

什麽是柯裏化?

柯裏化(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 

--> [].slice.call(arguments)通過arguments得到一個數組

--> [].push.apply(_args, [].slice.call(arguments))將數組Push到_args裏面

--> 再次調用時通過閉包保存了上一次返回的值

--> sum()最後運行時,arguments.length === 0,通過reduce方法求和

從例子中發現:sum(1,2,3)(4)通過閉包的方式保存了得到的值,不是每次都參與計算得到結果,而是在最後通過sum()才實現求和,以此能看出它的一個特點:延遲計算

en....貌似要是面試遇到這種題也能寫出個答案來了,但是了目前為止我還是無法學以致用,不明白這種函數適用於什麽場景

函數式編程之一柯裏化