熱身!
要實現三個幾個數相加,我們一定會這樣寫:
function add(a,b,c){
return a+b+c;
}
var total=add(1,2,3)複製程式碼
對啊,這樣寫沒錯。但是現在我要改需求了,要求--“結合閉包,函式只能有一個引數,並且完成以上能力”,這時候相信你已經想到了要用函式的柯里化來實現,牛逼!
在學習curring之前我們先來認識高階函式
高階函式?
高階函式的特點:
- 函式可以作為引數被傳遞;
- 函式可以作為返回值輸出。
顯然,JavaScript語言中的函式就滿足高階函式的條件。在實際開發中也有很多應用,我們現在就講講其中的一個應用--curring!
函式柯里化
curring也稱部分求值。為什麼?來講講它的概念,你就明白了。
一個curring的函式首先會接受一些引數,接受了這些引數後,該函式並不是立即求值,而是繼續返回另外一個函式,剛才傳入的引數在函式形成的閉包中被儲存起來。等到函式被真正需要求值的時候,之前傳入的所有引數都會被一次性用於求值。其實簡而言之就是:把一個接受N個引數的函式轉變成一個接受一個單一引數的函式,並且返回接受餘下引數的新函式。
扔了這麼多幹貨,到解決任務的時候了
柯里化簡單實現:
實現上面要求:
function curriedAdd(a){
return function(b){
return function(c){
return a+b+c;
console.log(a+b+c);
}
}
}
// 函式巢狀函式自動構成了閉包
curriedAdd(1)(2)(3)複製程式碼
函式只接受一個引數,並且返回一個函式。函式巢狀函式自動構成了閉包,閉合空間的引用一直保留,前兩次都沒有求值,其變數一直保留到最後一次求值。
到這裡大家肯定理解了function curring 了,那我們來個進階!
question:
如果我們要編寫一個計算每個月的開銷的函式。自然,要記錄下每天的開銷再求和。
程式碼實現:
var currying=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,l=arguments.length;i<1;i++){
money+=arguments[i];
}
return money;
}
})();
var cost=currying(cost);//轉化成curring函式
cost(100);//未真正求值
cost(200);//未真正求值
cost(300);//未真正求值
console.log(cost());//求值並輸出:600複製程式碼
這就實現了柯里化的函式。當呼叫cost()時,如果明確地帶上了一些引數,這裡的cost(100),cost(200),cost(300),表示此時並不進行真正的求職計算,而是把這些引數儲存起來,儲存在[]中,此時cost函式返回另外一個函式arguments.callee。只有當我們以不帶引數的形式執行cost()時,才利用前面儲存的所有,真正開始執行求值計算。