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