什么是柯理化函数

函数柯理化的表现是:把一个需要传入多个变量的函数变为多个嵌套函数,并且内层函数会调用上层函数的变量。

现在有一个简单的add函数:

function add(x, y) {
    return x + y;
}
console.log(add(1, 2)); // 3

将其改为柯理化函数

function add2(x) {
    return function (y) {
        return x + y;
    }
}

console.log(add2(1)(2)); // 3

从上面的例子可以看出,柯理化很像现在流行的组件化开发模式,将多个函数模块组合起来,得到一个新的函数。

柯理化函数的核心是闭包,因为闭包,所以内层函数才能够保留父作用域中的变量。

通用柯理化函数

1. 版本一

创建一个通用的柯理化函数的方式如下:

function currying(fun) {
    var args = Array.prototype.slice.call(arguments, 1);
    return function () {
        var _args = args.concat(Array.prototype.slice.call(arguments));
        return fun.apply(null, _args);
    }
}

可以看到,currying函数将除了第一个fn变量,将其他参数变量都赋值在args变量中,然后将其合并在返回函数的变量参数中,给返回函数使用。

现在,利用currying改造一个支持多个入参的add函数(采用ES6语法):

// 支持多个入参
function add(...vals) {
    return vals.reduce((pre, val) => {
        return pre + val;
    });
}

var newAdd = currying(add, 1, 2, 3);
console.log(newAdd(4, 5, 6)); // 21

这种方式创建的柯理化函数只能调用一次。

2. 版本二

再实现一种柯理化工厂函数,可以多次调用,最后统一求值。

function currying(fn) {
    var args = Array.prototype.slice.call(arguments, 1);

    return function () {
        if (arguments.length === 0) {
            return fn.apply(this, args);
        }
        else {
            Array.prototype.push.apply(args, arguments);
            return arguments.callee;
        }
    }
}

利用上面的currying改造add函数:

function add() {
    var vals = Array.prototype.slice.call(arguments);
    return vals.reduce((pre, val) => {
        return pre + val;
    });
}

var newAdd = currying(add, 1, 2, 3);
newAdd(4, 5);
newAdd(6, 7);

console.log(newAdd());  // 28

这种方式,把每次函数调用的参数都存储起来,如果已无参形式调用,说明记录结束,需要做最终计算。

小结

总之,柯理化就是利用模块化思想处理多参函数,通过组合函数减少每个函数的入参数量,从而提高代码的可阅读性及可维护性。

发布了203 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/z591102/article/details/105582584