函数柯里化(currying)

定义

函数柯里化是这样的一个转换过程,把接受多个参数的函数变换成接受一个单一参数(注:最初函数的第一个参数)的函数,如果其他的参数是必要的,返回接受余下的参数且返回结果的新函数。所谓“柯里化”就是使函数理解并处理部分应用

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. 参数复用;2. 提前返回;3. 延迟计算/运行。

参数复用

上面的例子就是一个应用,参数name被复用。

提前返回

很常见的一个例子,兼容现代浏览器以及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 ...,其实只要一次判定就可以了,怎么做?–柯里化。改为下面这样子的代码:

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的执行其实值实现了部分的应用(只有一次的if...else if...判定),而剩余的参数应用都是其返回函数实现的,典型的柯里化。

延迟计算/运行

想知道12月份4个周末总共钓了几斤鱼,可能就会下面这样实现:

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

若是有柯里化实现,则会是下面这样:

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

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

参考

JS中的柯里化(currying)
Js函数柯里化

你可能感兴趣的:(函数柯里化(currying))