93

我有一个用 JavaScript 实现的尾递归寻路算法,想知道是否有任何(所有?)浏览器可能会出现堆栈溢出异常。

4

6 回答 6

48

ECMAScript 4 规范原本打算增加对 TCO 的支持,但后来被放弃了:

JavaScript 中不再有尾调用?

据我所知,目前没有广泛可用的 JavaScript 实现实现自动 TCO。不过,这可能对您有用:

尾调用优化

本质上,使用累加器模式可以达到相同的效果。

于 2010-09-07T16:33:37.933 回答
26

暂时不高兴,但幸运的是,Harmony(ECMAScript 版本 6)有适当的尾调用 http://wiki.ecmascript.org/doku.php?id=harmony:proper_tail_calls

于 2011-05-07T20:25:28.027 回答
12

几乎您遇到的每个浏览器都会抱怨“递归过多”。这是 V8 错误跟踪器中的一个条目,可能会很有趣。

如果它是简单的自递归,那么使用显式迭代而不是希望消除尾调用可能是值得的。

于 2010-09-07T16:31:59.867 回答
12

未来 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当前版本的兼容表不再列出
于 2016-05-23T07:59:06.123 回答
3

尾调用优化现在可在编译为 JavaScript的LispyScript中使用。你可以在这里阅读更多关于它的信息。

于 2012-09-12T12:43:20.920 回答
2

目前没有 JavaScript 实现可以识别尾递归。ECMAScript 6中正在进行更改,正如其他人所说,V8上有一张公开票。

在这里,您可以看到 V8 为尾递归函数生成的汇编程序:

V8 如何编译递归的示例

将其与Clang如何在 C 中编译相同的函数进行比较

C 编译器尾递归示例

V8 保留了递归调用,而 C 编译器已识别尾递归并将其更改为循环。

于 2014-11-07T21:07:39.773 回答