在作項目的過程當中,遇到一個業務需求,須要用到柯里化。數組
接着回過頭看看什麼是柯里化。抄一段百度百科的解釋:閉包
在計算機科學中,柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,而且返回接受餘下的參數且返回結果的新函數的技術。app
對於咱們的關注點來講,重要的不是它是什麼,而是它能爲咱們作什麼。柯里化有三個常見的做用:1.參數複用,2.提早返回,3.延遲計算/運行。這裏咱們要用到它的第三個做用,延遲計算。函數
這裏看一個例子:debug
//Curry var curry = function(fn) { var args = [].slice.call(arguments, 1); //等同於arguments.slice(1); return function() { // 將新參數和以前的參數鏈接起來做爲curry函數中所傳入函數的參數。 var newArgs = args.concat([].slice.call(arguments)); return fn.apply(null, newArgs); }; } var add = function(x,y) { return x + y; } // 調用curry函數,傳入一個add方法和一個參數5,此時這裏的5等於上面的args。 var result = curry(add, 5) // 當調用result函數並傳入參數 10 時, // 將10和以前的參數5結合起來做爲以前curry函數中add方法的兩個參數, // 並運行執行,最終返回10。 console.log(result(10)); //15
在這裏,當咱們調用curry函數時,將5做爲curry函數中add方法的第一個參數,並保存起來,(這裏用到了閉包的知識,因此能保存,閉包之後再談,由於如今不會-_-!)而後在下面調用result方法並傳入參數10,此時參數 10 做爲add方法的第二個參數傳入,並執行。最終返回結果:15。
當咱們調用result方法時,不須要再顯示的傳入第一個參數,只須要傳入第二個參數便可完成方法調用。code
接下來,咱們人工debug一下這段代碼。在curry函數中,至少須要接受一個參數 fn,而後進入 var args = [].slice.call(arguments, 1);
這裏將在調用curry函數中,可能傳入的後續參數保存爲數組args。在curry函數return的function 中,這裏的function就是result。在return的函數中,將新傳入的參數與原來的args數組合併爲新的參數數組newArgs,並最終傳給fn,做爲fn 的參數。此時就完成了參數的合併。io
接着跑一下這段代碼,var result = curry(add, 5);
這裏傳入的參數5,被放到了args裏面保存起來等待與新的參數合併。 最後執行 result(10),10 做爲curry函數中,renturn function
裏面的新傳入的參數,與以前的args裏的5合併成爲[5,10],而後fn.apply(null, newArgs)
,新參數傳給fn,也就是這個add函數,調用add,最終返回結果 15.console
寫的有些亂,有看不懂的地方能夠提出來再修改下。固然,curry還有另外一種寫法curryRight.function
function curryRight(fn) { var args = [].slice.call(arguments, arguments.length - 1); return function() { var newArgs = [].concat([].slice.call(arguments), args); return fn.apply(null, newArgs); }; }
大同小異,本身體會。計算機科學