作为编程挑战的一部分,我们的任务是创建一个具有不确定数量的连续调用的函数。举个例子,假设函数只返回提供的参数的总和,它应该按如下方式工作:
sum(4)() // 4
sum(4)(5)() // 9
sum(4)(5)(9)() // 18
sum(4)(5)(9)(1)() // 19
// etc...
问题通过最后允许的空函数调用来简化,作为调用结束的指示。
我已经开发了一个解决方案来完成这项工作,但在函数内部使用全局变量:
var sum = function (a) {
if (!sum.init) {
sum.total = 0;
sum.init = true;
}
if (!arguments.length) {
sum.init = false;
return sum.total;
}
sum.total += a;
return sum;
};
此解决方案有效,但使用状态,全局变量和函数对象技巧,这是不理想的。我的问题是,是否有办法以纯粹的递归方式解决问题。
作为旁注,如果没有提供最后一次空调(),我不相信问题可以解决,但如果我错了请告诉我。
更新
此问题已在CodeReview中得到解答:https://codereview.stackexchange.com/a/153999/129579
一种不依赖于全局范围并且纯粹功能的网络解决方案。
答案 0 :(得分:3)
您可以使用闭包来实现您想要的内容:
function sum(value){
// the closure variable that will be accessible for all the _sum calls (initialised to 0 for every sum call).
var result = 0;
// the function that will be returned (sum will only get called once to initialize the result to 0. It's _sum which will be returned as much as possible)
function _sum(a){
// if we passed a parameter, then add it to result and return a new _sum
if(typeof a != "undefined"){
result += a;
return _sum;
}
// if we didn't return the result
else
return result;
}
// of course after initializing result we need to call _sum that handle the actual summing and return whatever it returns (if value is defined, it will return another `_sum` if not it will return the value of result which will be 0 at first) from now on sum will have nothing to do with the rest of the calls (()()()... )
return _sum(value);
}
console.log("sum() = " + sum());
console.log("sum(7)() = " + sum(7)());
console.log("sum(5)(6)(7)() = " + sum(5)(6)(7)());
// will return 0 because we call sum again
console.log("sum() = " + sum());

注意: sum(1)(7)(3)());
将按此顺序调用:
sum
参数为1
,会将result
初始化为0
并致电_sum
使用相同的参数1
将其添加到result
并返回_sum
的新因子,这将被调用以便以下_sum
调用7
,添加它并返回新的_sum
以便新的_sum
使用参数3
调用,...生成另一个_sum
没有参数,因此if(typeof a != "undefined")
将失败,而_sum
将返回result
。实际sum
仅在开始初始化时调用一次。正如我所说的那样,_sum
会在此之后被链接到最后。
答案 1 :(得分:0)
基本上,您可以使用外部函数sum
进行初始调用,并使用起始值a
和内部函数fn
进行闭包,该函数会重复返回,仅在{ {1}}等于零。
如果提供了值arguments.length
,则变量b
会更新,并返回内部函数a
。
fn
编辑调用sum而不带参数
function sum(a) {
return function fn(b) {
if (!arguments.length) {
return a;
}
a += b;
return fn;
};
}
console.log(sum(1)());
console.log(sum(1)(2)());
console.log(sum(1)(2)(3)());