柯里化

柯里化,即Currying,可以是函數(shù)變得更加靈活。我們可以一次性傳入多個參數(shù)調(diào)用它;也可以只傳入一部分參數(shù)來調(diào)用它,讓它返回一個函數(shù)去處理剩下的參數(shù)。

var add = function(x) {
    return function(y) {
        return x + y;
    };
};

console.log(add(1)(1)); // 輸出2

var add1 = add(1);
console.log(add1(1)); // 輸出2

var add10 = add(10);
console.log(add10(1)); // 輸出11

函數(shù)柯里化(function currying)又稱部分求值。一個currying的函數(shù)首先會接受一些參數(shù),接受了這些參數(shù)后,該函數(shù)并不會立即求值,而是繼續(xù)返回另外一個函數(shù),剛才傳入的參數(shù)在函數(shù)形成的閉包里被保存起來。待到函數(shù)真正需要求值的時候,之前傳入的參數(shù)都會被一次性用于求值。

假設(shè)我們要編寫一個計算每月開銷的函數(shù)。在每天結(jié)束之前,我們都要記錄今天花了多少錢,代碼如下:

var monthlyCost = 0;

var cost = function(money){
    monthlyCost += money;
};

cost(100);//第一天開銷
cost(200);//第二天開銷
cost(300);//第三天開銷
//cost(700);//第三十天開銷

alert(monthlyCost);//輸出:600

這段代碼在每天結(jié)束后都會記錄并計算到今天為止花了多少錢,但我們不太關(guān)心每天花掉多少,只想知道月底總共花掉了多少,也就是說,只需要在月底計算一次。

如果在每個月的前二十九天,我們都只是保存好當(dāng)天的開銷,直到第30天才進行求值計算,這就達到了我們的目的。下面的代碼還不是一個currying函數(shù)的完整實現(xiàn),但有助于我們了解其思想:

var cost = (function(){
    var args = [];
    
    return function(){
        if(arguments.length === 0){
            var money = 0;
            for(var i = 0, l = args.length; i < l; i++){
                money += args[i];
            }
            return money;
        }else{
            [].push.apply(args, arguments);
        }
    }
}());

cost(100);//未真正求值
cost(200);//未真正求值
cost(300);//未真正求值

console.log(cost());//求值并輸出:600

接下來編寫一個通用的function currying(){},它接受一個參數(shù),即將要被currying的函數(shù)。在這個例子里,這個函數(shù)的作用是遍歷本月每天的開銷并求出它們的總和。代碼如下:

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 < l; i++){
            money += arguments[i];
        }
        return money;
    }
}());

var cost = currying(cost);//轉(zhuǎn)化為currying函數(shù)

cost(100);//未真正求值
cost(200);//未真正求值
cost(300);//未真正求值

console.log(cost());//求值并輸出:600

至此,我們完成了一個currying函數(shù)的編寫,當(dāng)調(diào)用cost()時,如果明確帶上參數(shù),表明此時并不進行真正的求值計算,而是把這些參數(shù)保存起來,此時讓cost()函數(shù)返回另外一個函數(shù)。只有當(dāng)我們以不帶參數(shù)的形式執(zhí)行cost()時,才利用前面保存的所有參數(shù),真正開始求值計算。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容