在計算機科學中,柯里化(英語:Currying),又譯爲卡瑞化或加里化,是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,而且返回接受餘下的參數並且返回結果的新函數的技術。
以上是維基百科對於柯里化給出的定義,總結一下:javascript
fn()()()
這種方式調用寫一個經典的用來解釋柯里化的例子:java
function add(a, b, c) { return a + b + c; } const addTen = curry(add, 10); // curry就是後續咱們將實現的 柯里化函數 addTen(1)(2) // 13 addTen(3, 4) // 17
不難看出柯里化的用途之一就是參數複用,咱們能夠經過柯里化的方式很方便的實現參數複用,可能這樣你感受沒啥卵用,再來看下面例子:數組
const amount = [ { deposit: 120, finalPayment: 200 }, { deposit: 110, finalPayment: 300 }, { deposit: 130, finalPayment: 100 }, ]; // 按照deposit的值對數組進行排序 // 很容易想到這麼作 amount.slice().sort((a, b) => a.deposit - b.deposit); // 後來又須要對finalPayment進行排序 amount.slice().sort((a, b) => a.finalPayment - b.finalPayment); // 咱們再來使用柯里化的形式從新寫一下 const sort = curry(function(field, a, b) { return a[field] - b[field]; }) console.log(amount.slice().sort(sort('deposit'))); // deposit進行排序 console.log(amount.slice().sort(sort('finalPayment'))); // finalPayment進行排序
簡而言之:JavaScript中的柯里化實際上是利用閉包的特性,將全部參數都蒐集到以後再一併執行。
閉包
function fn(a, b, c, d, e...) {} // 經過柯里化 轉換爲 curryFn(a)(b)(c)(d)(e)(...)
對於add(a, b) {}
這樣的函數咱們很容易柯里化它app
function add(a, b) { return a + b; } function curry(fn, a) { return function(b) { return fn(a, b); } } curry(add, 10)(1); // 11
沒啥毛病,那我想作一個傳入三個參數的函數柯里化咋辦呢?安排~函數
function curry(fn, a) { return function(b) { return function(c) { return fn(a, b, c); } } }
那四個參數咋辦呢。。。很明顯這種方式並不具有通用性,其實仔細觀察上面的代碼,彷彿,彷佛,可能遞歸能實現:this
function curry(fn, ...args) { return function(...innerArgs) { const allArgs = [...args, ...innerArgs]; if (fn.length <= allArgs.length) { // 說明已經接受完全部參數,這個時候能夠執行了 return fn.apply(this, allArgs); } else { // 繼續返回函數,收集參數 return curry(fn, ...allArgs); } } }
以上就是關於柯里化的知識,但願對各位童鞋有所幫助。code