curry

by 郭 凡

JavaScript

//柯里化有3个常见作用:1. 参数复用;2. 提前返回;3. 延迟计算/运行
function curry (fn, length, args, holes) {
    length = length || fn.length;
    args = args || [];
    holes = holes || [];
    return function(){
        var _args = args.slice(0),
            _holes = holes.slice(0),
            argStart = _args.length,
            holeStart = _holes.length,
            arg, i;
        for(i = 0; i < arguments.length; i++) {
            arg = arguments[i];
            if(arg === '_' && holeStart) {
                holeStart--;
                _holes.push(_holes.shift()); 
// move hole from beginning to end

            } else if (arg === '_') {
                _holes.push(argStart + i); 
// the position of the hole.

            } else if (holeStart) {
                holeStart--;
                _args.splice(_holes.shift(), 0, arg); 
// insert arg at index of hole

            } else {
                _args.push(arg);
            }
        }
        if(_args.length < length) {
            return curry.call(this, fn, length, _args, _holes);
        } else {
            return fn.apply(this, _args);
        }
    }
}

//1.参数复用
var sum = function(a,b) {
	return a+b;
}
var curry_sum = curry(sum);
var sum_one = curry_sum(1);
var result_1 = sum_one(2);//3
var result_2 = sum_one(3);//4
console.log(result_1, result_2);
//2.提前返回
//每次调用都执行if else
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);
        });
    } 
};
//只执行一次if else
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) {
      ...