【问题标题】:Tail function in javascript [duplicate]javascript中的尾函数[重复]
【发布时间】:2015-03-31 19:17:04
【问题描述】:

我想创建一个添加参数的函数。调用这个函数应该是

functionAdd(2)(3)(4)...(n);

结果 2+3+4...+n 我正在尝试这个

function myfunction(num){
  var summ =+ num;
  if(num !== undefined){
    return myfunction(summ);
  }

};

但它不起作用,ovwerflow的错误。而且我不明白我应该从这个函数中哪里出来;

【问题讨论】:

  • 所以你想要一个返回函数的函数(因为它可以被调用)......除非它是最后一次,它返回一个数字?它怎么知道这是最后一次?
  • 您应该返回一个函数引用,同时返回myfunction(summ) 返回的结果。尝试用一张纸手动评估它。
  • 顺便说一句,调用本身看起来很奇怪 - 原来的任务是什么?你确定functionAdd(2)(3)(4)...(n);是你必须实现的吗?
  • 你的意思是你应该将n 传递给一个函数,并返回N 的总和,直到> 1?如果是这样,那很容易。只要让summ的作用域大于函数,如果num > 0就调用它

标签: javascript recursion tail-recursion


【解决方案1】:

您可以使用.valueOf 来解决问题:

function myfunction(sum){
    var accum = function(val) {
        sum += val;

        return accum;
    };

    accum.valueOf = function() {
        return sum;
    };

    return accum(0);
};

var total = myfunction(1)(2)(3)(4);

console.log(total); // 10

JSFiddle:http://jsfiddle.net/vdkwhxrL/

它是如何工作的:

在每次迭代中,您都会返回对累加器函数的引用。但是当您请求结果时 - 调用 .valueOf() 时,它会返回一个标量值。

请注意,结果仍然是一个函数。最重要的是,这意味着它不会在分配时被复制:

var copy = total
var trueCopy = +total   // explicit conversion to number

console.log(copy)       // 10 ; so far so good
console.log(typeof copy)  // function
console.log(trueCopy)   // 10
console.log(typeof trueCopy)  // number

console.log(total(5))   // 15

console.log(copy)       // 15 too!
console.log(trueCopy)   // 10

【讨论】:

  • 不错的把戏。当然,只有在标量上下文中使用最终结果时才有效。您可以通过使用一元 + 运算符来简洁地强制执行此操作。
  • @Touffy 好吧,应该在需要标量的上下文中使用返回数字的函数 :-) 否则没有意义。
  • 不过,最好记住这个特定值不是数字。它对数字有一些相当不寻常的属性,可以调用,将通过引用复制或传递而不是复制值……例如,如果将它分配给另一个变量,然后用数字调用原始变量,它将改变另一个变量的“值”也是
  • @zerkms 非常感谢!现在我可以去睡觉了……
  • @Touffy 确实是一个额外的有效点 :-) 奇怪的任务需要奇怪的解决方案(有其局限性)
【解决方案2】:

如果最后一次调用可以不带参数:

function add(value) {

  var sum = value;

  return function add(value) {
    if(typeof value === 'number') {
      sum += value
      return add
    } else {
      return sum
    }
  }

}



console.log(add(1)(2)(3)(0)()) // 6

【讨论】:

    猜你喜欢
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-18
    • 2012-10-18
    • 1970-01-01
    • 2020-10-04
    • 2012-06-17
    相关资源
    最近更新 更多