實現柯里化
阿新 • • 發佈:2022-05-29
柯里化是什麼?
把接收多個引數的函式,變成接收一個單一引數(最初函式的第一個函式)的函式,並且返回接受餘下的引數,而且返回的結果的新函式的技術。
如果你固定某些引數,你將得到接收餘下引數的一個函式。
總結:
- 只傳遞給函式一部分引數來呼叫它,讓它返回一個函式去處理剩餘的引數;
- 這個過程就稱之為柯里化
例如:
function foo(m, n, x, y) { return m + n + x + y; } foo(m + n + x + y) // 柯里化過程 function bar(m) { return function(n) { return function (x) { return function (y) { return m + n + x + y; } } } } // 呼叫 bar(10)(20)(30)(40)
為什麼要實現柯里化?
在函數語言程式設計中,我們希望一個函式處理的問題儘可能單一,而不是將一大堆的處理過程交給一個函式來處理;
柯里化就可以用來實現這個過程,可以將每次傳入的引數在單一的函式中進行處理,處理完成後在下一個函式中再使用處理後的結果。
例如:
// 實現對錯誤的日誌輸出 /* var log = function(date) { return function(type) { return function(message) { console.log(`[${date.getHours()}:${date.getMinutes()}][${type}]:[${message}]`) } } } */ // 利用箭頭函式進行優化 var log = date => type => message => { console.log(`[${date.getHours()}:${date.getMinutes()}][${type}]:[${message}]`) } var nowlog = log(new Date()) newlog("debug")("查詢到了新的bug") newlog("info")("https請求成功") var nowDebuglog = log(new Date())("debug") nowDebuglog("查詢到了新的bug") nowDebuglog("首頁資料獲取成功")
用了柯里化後你就會發現,我們可以不必一次性得傳遞函式的所有引數,可以對函式進行定製化的處理。
這可以稱之為函式的單一職責原則,我們可以用過柯里化的設計,在一個函式裡做一件事情。
怎麼實現
實現柯里化主要是用於實現以下兩點:
- 柯里化後的函式可以分批接收引數。
- 柯里化的函式會生成新函式,將剩餘的引數返回一個新的函式接收。
柯里化實現:
我們將要對下面這樣一個函式(add)實現柯里化。
function add(num1, num2, num3) { console.log(this, num1 + num2 + num3) } var curryadd = mjyCurrying(add) // mjyCurrying() 函式將模擬實現柯里化的過程 curryadd(10, 20, 30) // 一次性接收全部引數 curryadd.call('111',10, 20, 30) // 可以通過call改變this指向 curryadd(10)(20)(30) // 分批接收引數 curryadd(10)(20,30) // 分批接收引數
mjyCurrying 函式通過遞迴實現模擬柯里化過程
function mjyCurrying(fn) {
function curried(...args) {
// 如果引數第一步就傳遞夠了
if ( args.length >= fn.length ) {
// 有可能在呼叫的時候需要改變this指向,我們這裡用進行this的繫結
return fn.call(this, ...args)
} else {
// 引數不夠,需要返回一個新的引數,繼續來接收剩餘的引數(對curried進行回撥)
function callback_curried(...args2) {
return curried.call(this, ...args, ...args2)
}
return callback_curried
}
}
return curried
}