curring又稱爲部分求值,一個curring的函數,會首先接受一些參數,接受了這些參數之後,該函數並不會立即求值,而是繼續返回另一個函數,剛纔傳入的參數在函數形成的閉包中被保存起來,待到函數真正需要求值的時候,之前傳入的所有參數都會被一次性用於求值 。
何時使用curry
當發現正在調用同一個函數,並且傳遞的參數絕大多數都是相同的,那麼該函數可能是用於curry化的一個很好的候選參數。可以通過將一個函數集合部分應用到函數中,從而動態創建一個新函數。
curry化函數的示例1
//柯里化函數
function curring(fn){
var slice = Array.prototype.slice,
stored_args = slice.call(arguments, 1);//截取函數之後的所有參數
return function() {
var new_args = slice.call(arguments),
args = stored_args.concat(new_args);//合併數組
return fn.apply(null, args);//傳null的時候,this對象爲windows
};
}
//普通函數
function add(a, b, c, d, e){
return a + b + c + d + e;
}
//可運行於任意數量的參數
curring(add,1, 2, 3)(5, 5);//16
//兩步curry化
var addone = curring(add, 1);
addOne(10, 10, 10, 10);//41
var addSix = curring(addOne, 2, 3);
addSix(5, 5);//16
《Javascript patterns》 Page87
示例2
var curring = function(fn){
var args = [];
return function(){
if(arguments.length === 0){
return fn.apply(this,args);
}else{
[].push.apply(args,arguments);
return arguments.callee;
}
}
}
//求值函數
var cost = (function(){
var money = 0;
return function(){
for(var i= 0;i < arguments.length;i++){
money += arguments[i];
}
return money;
}
})();
var cost1 = curring(cost);
cost1(100);//未真正求值
cost1(200);//未真正求值
cost1(300);//未真正求值
alert(cost1());//真正求值600
Javascript設計模式與開發實踐 page50