函數(shù)柯里化幸冻,其實就是高階函數(shù)的一個應用空镜。
什么是高階函數(shù)呢浩淘,就是將一個函數(shù)A作為另一個函數(shù)B的參數(shù), B就是一個高階函數(shù)缓窜。
所謂"柯里化"币旧,就是把一個多參數(shù)的函數(shù)灾炭,轉(zhuǎn)化為單參數(shù)函數(shù)檬嘀。
柯里化是指這樣一個函數(shù)(假設叫做createCurry)峭状,他接收函數(shù)A作為參數(shù)谅河,運行后能夠返回一個新的函數(shù)行施。并且這個新的函數(shù)能夠處理函數(shù)A的剩余參數(shù)延刘。
**
舉個例子:
const add = (x, y) => x + y;
add(1, 2) //3
??上訴代碼就很簡單的一個求和計算值镣隶。
如果用柯里化函數(shù)思想我們可以寫成這樣??
首先我們得有個接受兩個參數(shù)的通用柯里化函數(shù):
const curry = (binaryFn) => {
return function (firstArg) {
return function (secondArg) {
return binaryFn (firstArg, secondArg) ; // 為啥要嵌套那么多呢极谊?基于什么思路呢?思考一下...
};
};
};
然后把add函數(shù)轉(zhuǎn)化成一個柯里化的版本
const add = (x, y) => x + y;
const autoCurriedAdd = curry(add);
autoCurriedAdd(1)(2) // 3
通過比較安岂,柯里化函數(shù)明顯把簡單問題復雜化了怀酷,這個時候為啥還要用呢?
當然這只是其中的一個場景而已嗜闻! 如果場景很多呢蜕依,然后都是接受兩個參數(shù),那么這個模板的作用就起來了琉雳。
比如說我們有個函數(shù)const mul = (x, y) => x * y
;
如果我們柯里化一下
const autoCurriedAdd = curry(mul);
autoCurriedAdd(1)(2) // 2

image.png
當然上訴展示的只是兩個參數(shù)的柯里化模板样眠,三個參數(shù)可以依葫蘆畫瓢,如下:
const curry = (binaryFn) => {
return function (firstArg) {
return function (secondArg) {
return function (thirdArg) {
return binaryFn (firstArg, secondArg, thirdArg) ; // 為啥要嵌套那么多呢翠肘?基于什么思路呢檐束?思考一下...
};
};
};
};
那么參數(shù)越來越多呢,那可咋整束倍?
這個時候遞歸就出來了1簧ァ!绪妹!
// 柯里化函數(shù)
const curry = (fn) => {
if (typeof fn !== 'function') {
throw Error('No function provided')
}
return function curriedFn (...args) {
if (fn.length > args.length) { // 未達到觸發(fā)條件甥桂,繼續(xù)收集參數(shù)
return function () {
return curriedFn.apply(null, args.concat([].slice.call(arguments)))
}
}
return fn.apply(null, args)
}
}
這樣我們就可以接受多個參數(shù)了。
const multiply = (x, y, z, t) => x * y * z * t;
const curryMul = curry(multiply);
const result = curryMul(1)(2)(3)(4); // 1*2*3*4 = 24

image.png
這就很棒了邮旷,剩下的自己拓展吧;蒲 !婶肩!