我有一个尾递归寻路算法,我在Javascript中实现,想知道是否有任何(所有?)浏览器可能会出现堆栈溢出异常。
答案 0 :(得分:47)
ECMAScript 4规范原本会增加对TCO的支持,但它已被删除。
http://lambda-the-ultimate.org/node/3047
据我所知,目前没有广泛可用的JS实现自动TCO。不过,这可能对您有用:
http://www.paulbarry.com/articles/2009/08/30/tail-call-optimization
基本上,使用累加器模式可以达到同样的效果。
答案 1 :(得分:26)
暂时没有欢乐,但幸运的是正确的尾调用于和谐(ECMAScript第6版) http://wiki.ecmascript.org/doku.php?id=harmony:proper_tail_calls
答案 2 :(得分:12)
你遇到的每一个浏览器都会“过多递归”。这是entry in the V8 bug tracker,可能是有趣的阅读。
如果它是简单的自递归,那么使用显式迭代而不是希望消除尾部调用可能是值得的。
答案 3 :(得分:8)
将支持尾部调用优化ECMAScript 6将来的严格模式。查看http://www.2ality.com/2015/06/tail-call-optimization.html了解详情。
检查http://kangax.github.io/compat-table/es6/以获取当前的引擎支持。
目前(05-01-2018),以下引擎支持尾调用优化:
支持“实验性JavaScript功能”-flag打开:
答案 4 :(得分:3)
现在可以在LispyScript中使用尾部调用优化,它可以编译为javascript。您可以阅读更多相关信息here。
答案 5 :(得分:2)
目前没有JS实现识别尾递归。 ECMAScript 6正在进行更改,正如其他人所说,V8上有一张开放票据
在这里,您可以看到V8为尾递归函数生成的汇编程序
https://gist.github.com/mcfedr/832e3553964a014621d5
将其与clang在C
中编译相同函数的方式进行比较https://gist.github.com/mcfedr/63ad08370d856bad3694
V8保留递归调用,而C编译器已识别尾递归并将其更改为循环