简介
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函数返回另外一个函数。只有当我们以不带参数的形式执行,才利用前面保存的所有函数,真正开始进行求值计算。