关于尾递归优化问题

为什么我使用了尾递归优化,还是会产生调用栈溢出的情况呢?
代码如下:

function tcoFactorial(n, index = 1, lastResult = 1) {
  if(n === 1) {
    return lastResult
  } else {
    return tcoFactorial(n-1, index + 1, lastResult * (index+1))
  }
}
console.log(tcoFactorial(100000))

错误:

RangeError: Maximum call stack size exceeded
阅读 3.7k
5 个回答

你这是改成了尾递归,但还是执行函数的时候还是会不停的压函数进栈,最终爆栈,原因是执行环境根本没有尾递归优化,最终还是会有100000个函数调用进栈。

函数调用通常会把很多信息(作用域、参数、环境)等压入栈中,函数执行完毕后出栈。

尾递归优化是JS引擎实现的,它的原理其实是这样的,在你函数tcoFactorial(1000,1,1)调用tcoFactorial(999,2,1*2)的时候,原本的这个tcoFactorial(1000,1,1)其实毫无作用了,它的栈信息已经用不到了,所以它可以剥离出栈,因为它的结果已经是tcoFactorial(999,2,1*2)了,所以我们只需要在栈里保存这下一级即可。

尾递归优化后,你tcoFactorial(1000)的时候,在栈里只需要一个调用,所以最终不会爆栈。

然而,现有的浏览器除了苹果家Safari支持,其他的执行环境基本上都不支持,chrome曾经短暂的实现过一次,后来又下架了这个特性,所以说根本没有尾递归优化。

这个特性的支持度参照:http://kangax.github.io/compa...

chrome52短暂的支持如下,现在已经不再支持了:
4ddead09jw1f3i7mhtv02j20o20k0wil.jpg

顺便说一下,尾递归这个ES6特性,标准委员会成员们还在撕逼当中,他们分成两派,其中有一派人希望以显示关键字指引尾递归优化,所以这个特性至今未能铺开。

很有可能撕逼个一年两年的。

你这不是优化的问题,浏览器算不出来的好不好,500就是Infinity了,搞不懂你要算什么

只是数字太大了计算不出来而已

数值太大计算不出来
当你是1000的时候lastResult就无限大了
更别说100000

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题