curry 的概念:只傳遞給函數一部分參數來調用它,讓它返回一個函數去處理剩下的參數
先看一個簡單例子,add
函數接受 2 個參數(或者多個),addX
函數接受 1 個參數。
換而言之,所謂"柯里化",就是把一個多參數的函數,轉化爲單參數函數。將一個函數轉換爲一個新的函數javascript
// 非柯里化 function add(x, y) { return x + y; } add(1, 2) === 3; // true // 柯里化 function addX(y) { return function(x) { return x + y; }; } addX(2)(1) == 3; // true
我能想到的是:html
"函數式編程"是一種"編程範式"(programming paradigm),也就是如何編寫程序的方法論。
因此,不用想太多,就是一種規範同樣的東西~ ~java
先來看一個栗子(這裏藉助了ramda
,請自行安裝),在下面的栗子中咱們對 add 進行了柯里化,從結果上能夠看到當參數爲 1 個時返回的是個函數,當參數爲 2 個的時候返回函數,當參數爲 3 個的時候返回函數執行結果
。git
var _ = require("ramda"); var add = function(a, b, c) { return a, b, c; }; var curry_add = _.curry(add); console.log(curry_add(1)); // 輸出函數 console.log(curry_add(1)(2)); // 輸出函數 console.log(curry_add(1)(2)(3)); // 輸出結果
根據上述的小栗子,能夠獲得,柯里化後的函數
若是接受到所有參數則返回函數執行結果
,不然返回一個柯里化函數
。編程
很容易想到如下僞代碼segmentfault
var curry = function(fn) { return function() { // 假設柯里化的函數叫 curry_fn // if "curry_fn接受到的參數數量等於fn接受參數的數量" // return "fn的執行結果" // else return "一個柯里化函數" }; };
上述僞代碼是否是很像遞歸?app
因而有了如下簡單實現柯里化的代碼ide
var curry = function(fn) { var limit = fn.length; // fn接受的參數個數 var params = []; // 存儲遞歸過程的全部參數,用於遞歸出口計算值 return function _curry(...args) { params = params.concat(args); // 收集遞歸參數 if (limit <= params.length) { // 返回函數執行結果 return fn.apply(null, params); } else { // 返回一個柯里化函數 return _curry; } }; };