在計算機科學中,柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,而且返回接受餘下的參數且返回結果的新函數的技術。這個技術由 Christopher Strachey 以邏輯學家 Haskell Curry 命名的,儘管它是 Moses Schnfinkel 和 Gottlob Frege 發明的。閉包
函數柯里化(function currying)又稱部分求值。一個currying的函數首先會接受一些參數,接受了這些參數後,該函數並不會當即求值,而是繼續返回另一個函數,剛纔傳入的參數在函數造成的閉包裏被保存起來。待到函數真正須要求值的時候,以前傳入的參數都會被一次性用於求值。app
假設咱們要編寫一個計算每個月開銷的函數。在天天結束以前,咱們都要記錄今天花了多少錢,代碼以下:函數
let result = 0; let add = function(num){ result += num; console.log(result); } add(10); // 10 add(5); // 15 add(8); // 23
這段代碼在天天結束後都會記錄並計算到今天爲止花了多少錢,但咱們不太關心天天花掉多少,只想知道月底總共花掉了多少,也就是說,只須要在月底計算一次。spa
若是在每月的前二十九天,咱們都只是保存好當天的開銷,直到第30天才進行求值計算,這就達到了咱們的目的。prototype
最終,咱們要實現這樣的方案,curry函數能夠屢次調用,每次調用的參數不定;當函數調用無參數時,輸出最終結果code
// curry - 柯里化函數 // fn - 計算結果的函數 // args - 參數 curry(fn, args...)(args...)(args...)();
廢話很少說,直接上代碼:blog
let add = function(){ let args = Array.prototype.slice.call(arguments); let result = 0; args.forEach((item, key)=>{ result += item; }) console.log(result); return result; } let curry = function(fn){ let args = Array.prototype.slice.call(arguments, 1); return function(){ let args_add = Array.prototype.slice.call(arguments); let newArgs = args.concat(args_add); if(args_add.length){ // 當函數調用無參數時,計算結果 return curry.call(null, fn, ...newArgs); }else{ // 當函數調用有參數時,保存參數,做爲下次調用的參數 return fn.apply(null, newArgs); } } } curry(add, 1, 2)(4, 5)(); // 12
一、延遲計算。(就像烹飪同樣,食材所有準備好後,廚師纔開始作菜)it
二、參數複用。當在屢次調用同一個函數,而且傳遞的參數絕大多數是相同的,那麼該函數多是一個很好的柯里化候選。io
三、動態建立函數。這能夠是在部分計算出結果後,在此基礎上動態生成新的函數處理後面的業務,這樣省略了重複計算。或者能夠經過將要傳入調用函數的參數子集,部分應用到函數中,從而動態創造出一個新函數,這個新函數保存了重複傳入的參數(之後沒必要每次都傳)console
歡迎你們指正嘍,哈哈