我有一个用 JavaScript 实现的尾递归寻路算法,想知道是否有任何(所有?)浏览器可能会出现堆栈溢出异常。
6 回答
ECMAScript 4 规范原本打算增加对 TCO 的支持,但后来被放弃了:
据我所知,目前没有广泛可用的 JavaScript 实现实现自动 TCO。不过,这可能对您有用:
本质上,使用累加器模式可以达到相同的效果。
暂时不高兴,但幸运的是,Harmony(ECMAScript 版本 6)有适当的尾调用 http://wiki.ecmascript.org/doku.php?id=harmony:proper_tail_calls
几乎您遇到的每个浏览器都会抱怨“递归过多”。这是 V8 错误跟踪器中的一个条目,可能会很有趣。
如果它是简单的自递归,那么使用显式迭代而不是希望消除尾调用可能是值得的。
未来 ECMAScript 6 严格模式将支持尾调用优化。详情请查看http://www.2ality.com/2015/06/tail-call-optimization.html。
检查http://kangax.github.io/compat-table/es6/以获取当前的引擎支持。
目前(18-07-2019)以下引擎支持尾调用优化:
- 野生动物园 >= 10
- iOS >= 10
- 京诺 XS6
- 杜克胶带 2.3
如果“experimental JavaScript features”标志打开,则支持:
- 节点 6.5
Chrome 54 / Opera 41当前版本的兼容表不再列出
尾调用优化现在可在编译为 JavaScript的LispyScript中使用。你可以在这里阅读更多关于它的信息。
目前没有 JavaScript 实现可以识别尾递归。ECMAScript 6中正在进行更改,正如其他人所说,V8上有一张公开票。
在这里,您可以看到 V8 为尾递归函数生成的汇编程序:
将其与Clang如何在 C 中编译相同的函数进行比较
V8 保留了递归调用,而 C 编译器已识别尾递归并将其更改为循环。