【问题标题】:javascript Factorial function got RangeErrorjavascript 阶乘函数得到 RangeError
【发布时间】:2018-12-26 12:40:41
【问题描述】:
const factorial = function(n, acc = 1){
  if (n < 2) {
    return acc;
  }
  return factorial(n - 1, n * acc); 
};
const factorial_normal = function(n){
  if (n < 2) {
    return 1;
  }
  return n * factorial_normal(n - 1)
};
console.log(factorial(8956)); // RangeError: Maximum call stack size exceeded
console.log(factorial_normal(8960)); // Infinity

这只是一个简单的 javascript 阶乘函数。 但是我在第一个函数中得到了 RangeError,我认为这是一个更好的解决方案,因为我认为它更快并且更节省堆栈。 我所知道的这两个功能有什么不同吗? 请帮助我,谢谢。

【问题讨论】:

  • ps。我使用节点 v10.0.0
  • '超出最大调用堆栈大小' 欢迎来到递归世界。您刚刚遇到了该站点的名称源自的错误。
  • 啊,see this other question. 看起来曾经可用的尾调用已经从 Node 中删除了。
  • 您可以不使用递归来执行此操作,而是使用简单的 for 循环,这取决于传入的数字,这很容易破坏堆栈。
  • @AdamH 是的,我认为你是对的。循环样式丑陋但有效。即使 factorial(1000000...) 也很顺利:)

标签: javascript node.js v8


【解决方案1】:

由于 Node.js 不支持尾调用优化,这两个函数都会在某些时候抛出 RangeError: Maximum call stack size exceeded 错误。何时发生这种情况取决于两个量:堆栈的最大允许大小和每个单独的堆栈帧的大小。默认情况下,堆栈的大小设置为某个常数值,您可以通过运行以下命令获得:

node --v8-options | grep -e '--stack-size' -A 1

所以,剩下的唯一参数是堆栈帧的大小。 factorial 在每次函数调用时在堆栈上存储两个变量 - accn。而factorial_normal 只存储一个 - n。这意味着factorial 将比factorial_normal 更快地耗尽堆栈空间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    • 2021-01-17
    • 2019-08-06
    • 1970-01-01
    • 1970-01-01
    • 2022-06-24
    • 2016-06-10
    相关资源
    最近更新 更多