创建具有不确定数量的连续调用的函数

时间:2017-01-30 13:16:32

标签: javascript functional-programming

作为编程挑战的一部分,我们的任务是创建一个具有不确定数量的连续调用的函数。举个例子,假设函数只返回提供的参数的总和,它应该按如下方式工作:

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

一种不依赖于全局范围并且纯粹功能的网络解决方案。

2 个答案:

答案 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)());将按此顺序调用:

  1. sum参数为1,会将result初始化为0并致电
  2. _sum使用相同的参数1将其添加到result并返回_sum的新因子,这将被调用以便以下
  3. 使用参数_sum调用
  4. 7,添加它并返回新的_sum以便新的
  5. _sum使用参数3调用,...生成另一个
  6. _sum没有参数,因此if(typeof a != "undefined")将失败,而_sum将返回result
  7. 实际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)());