函數(shù)柯里化(currying)

定義

函數(shù)柯里化是這樣的一個轉(zhuǎn)換過程,把接受多個參數(shù)的函數(shù)變換成接受一個單一參數(shù)(注:最初函數(shù)的第一個參數(shù))的函數(shù),如果其他的參數(shù)是必要的,返回接受余下的參數(shù)且返回結(jié)果的新函數(shù)。所謂“柯里化”就是使函數(shù)理解并處理部分應(yīng)用。

function curry(func){
    var args = [].slice.call(arguments,1),self = this;
    return function(){
        var newArgs = args.concat([].slice.call(arguments,0));
        func.apply(self,newArgs);
    }
}
function say(name,tosay){
    console.log(name + tosay);
}
var tosay = curry(say,"tiger");
tosay("nihao");
tosay("byebye");

作用

概括起來有三個作用:1. 參數(shù)復(fù)用;2. 提前返回;3. 延遲計(jì)算/運(yùn)行。

參數(shù)復(fù)用

上面的例子就是一個應(yīng)用,參數(shù)name被復(fù)用。

提前返回

很常見的一個例子,兼容現(xiàn)代瀏覽器以及IE瀏覽器的事件添加方法。我們正常情況可能會這樣寫:

var addEvent = function(el, type, fn, capture) {
    if (window.addEventListener) {
        el.addEventListener(type, function(e) {
            fn.call(el, e);
        }, capture);
    } else if (window.attachEvent) {
        el.attachEvent("on" + type, function(e) {
            fn.call(el, e);
        });
    } 
};

上面的方法有什么問題呢?很顯然,我們每次使用addEvent為元素添加事件的時候,(eg. IE6/IE7)都會走一遍if...else if ...,其實(shí)只要一次判定就可以了,怎么做?–柯里化。改為下面這樣子的代碼:

var addEvent = (function(){
    if (window.addEventListener) {
        return function(el, sType, fn, capture) {
            el.addEventListener(sType, function(e) {
                fn.call(el, e);
            }, (capture));
        };
    } else if (window.attachEvent) {
        return function(el, sType, fn, capture) {
            el.attachEvent("on" + sType, function(e) {
                fn.call(el, e);
            });
        };
    }
})();

初始addEvent的執(zhí)行其實(shí)值實(shí)現(xiàn)了部分的應(yīng)用(只有一次的if...else if...判定),而剩余的參數(shù)應(yīng)用都是其返回函數(shù)實(shí)現(xiàn)的,典型的柯里化。

延遲計(jì)算/運(yùn)行

想知道12月份4個周末總共釣了幾斤魚,可能就會下面這樣實(shí)現(xiàn):

var fishWeight = 0;
var addWeight = function(weight) {
    fishWeight += weight;
};

addWeight(2.3);
addWeight(6.5);
addWeight(1.2);
addWeight(2.5);

console.log(fishWeight);   // 12.5

若是有柯里化實(shí)現(xiàn),則會是下面這樣:

var curryWeight = function(fn) {
    var _fishWeight = [];
    return function() {
        if (arguments.length === 0) {
            return fn.apply(null, _fishWeight);
        } else {
            _fishWeight = _fishWeight.concat([].slice.call(arguments));
        }
    }
};
var fishWeight = 0;
var addWeight = curryWeight(function() {
    var i=0; len = arguments.length;
    for (i; i<len; i+=1) {
        fishWeight += arguments[i];
    }
});

addWeight(2.3);
addWeight(6.5);
addWeight(1.2);
addWeight(2.5);
addWeight();    //  這里才計(jì)算

console.log(fishWeight);    // 12.5

本部分主要是參考了JS中的柯里化(currying)這邊文章,希望大家去看原文。

參考

JS中的柯里化(currying)
Js函數(shù)柯里化

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

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

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