高階函數應用--currying

熱身!

要實現三個幾個數相加,咱們必定會這樣寫:bash

function add(a,b,c){
           return a+b+c;
       }
    var total=add(1,2,3)複製代碼

對啊,這樣寫沒錯。可是如今我要改需求了,要求--「結合閉包,函數只能有一個參數,而且完成以上能力」,這時候相信你已經想到了要用函數的柯里化來實現,牛逼!閉包

在學習curring以前咱們先來認識高階函數

高階函數?

高階函數的特色:app

  • 函數能夠做爲參數被傳遞;
  • 函數能夠做爲返回值輸出。

顯然,JavaScript語言中的函數就知足高階函數的條件。在實際開發中也有不少應用,咱們如今就講講其中的一個應用--curring!函數

函數柯里化

curring也稱部分求值。爲何?來說講它的概念,你就明白了。學習

一個curring的函數首先會接受一些參數,接受了這些參數後,該函數並非當即求值,而是繼續返回另一個函數,剛纔傳入的參數在函數造成的閉包中被保存起來。等到函數被真正須要求值的時候,以前傳入的全部參數都會被一次性用於求值。其實簡而言之就是:把一個接受N個參數的函數轉變成一個接受一個單一參數的函數,而且返回接受餘下參數的新函數。ui

扔了這麼多幹貨,到解決任務的時候了

柯里化簡單實現:

實現上面要求:this

function curriedAdd(a){
        return function(b){
            return function(c){
                return a+b+c;
                console.log(a+b+c);
            }
        }
    }
// 函數嵌套函數自動構成了閉包
curriedAdd(1)(2)(3)複製代碼

函數只接受一個參數,而且返回一個函數。函數嵌套函數自動構成了閉包,閉合空間的引用一直保留,前兩次都沒有求值,其變量一直保留到最後一次求值。spa

到這裏你們確定理解了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()時,才利用前面保存的全部,真正開始執行求值計算。code

若是你以爲收穫了currying,感謝star 😄

相關文章
相關標籤/搜索