currying

116 阅读2分钟

简介

currying又称部分求值。一个currying的函数首先会接收一些参数,接收了这些参数之后,该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来。待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。

例子

假设我们需要一个计算每月开销的函数。在每天结束之前,我们都需要记录今天花掉了多少钱

        var moonthlyCost = 0;
        var cost = function (money) {
            moonthlyCost += money
        }
        cost(100)//第一天
        cost(200)//第二天
        cost(300)//第三天
        alert(moonthlyCost) //600

通过这段代码可以看到,每天结束后我们都会记录并计算到今天为止花掉的钱。但我们其实并不太关心每天花掉了多少钱,而只想知道月底的时候会花掉多少钱。也就是说,实际上只需要月底计算一次。

如果再每个月的前29天,我们都只是保存好当天的开销,直到第30天才进行求值计算,只样就达到了我们的要求。

        var cost = (function () {
            let args = [];
            return function () {
                if (arguments.length === 0) {
                    var money = 0;
                    for (let i = 0; i < args.length; i++) {
                        money += args[i]
                    }
                    return money;
                } else {
                    [].push.apply(args, arguments);
                }
            }
        })();
        cost(100);
        cost(200);
        cost(300);
        console.log(cost())

接下来编写一个通用的 function currying(){}, function currying(){}接收一个参数,即将要背currting的函数,在下个列子中,这个函数的作用遍历本月每天的开销并求出它们的总和

        var currying = (function (func) {
            let args = [];
            return function () {
                if (arguments.length === 0) {
                    return func.apply(this, args);
                } else {
                    [].push.apply(args, arguments);
                    return arguments.callee
                }
            }
        });

        var cost = (function () {
            var money = 0;
            return function () {
                for (let i = 0; i < arguments.length; i++) {
                    money += arguments[i];
                }
                return money
            }
        })();
        var costa = currying(cost);
        costa(100);
        costa(200);
        costa(300);
        console.log(costa())

至此,我们完成了一个currying函数的编写。当调用cost()时,如果明确地带上了一些参数,表示此时不进行真正的求值计算,而是把这些参数保存起来,此时让cost函数返回另外一个函数。只有当我们以不带参数的形式执行,才利用前面保存的所有函数,真正开始进行求值计算。