下面是两个阶乘实现从这个地方
尾呼叫优化(TCO):
function fact(n) {
return tail_fact(n,1) ;
}
function tail_fact(n,a) {
if (n == 0)
return a ;
else
return tail_fact(n-1,n*a) ;
}和用延续式编程(回调)重写的一个:
function fact(n,ret) {
tail_fact(n,1,ret) ;
}
function tail_fact(n,a,ret) {
if (n == 0)
ret(a) ;
else
tail_fact(n-1,n*a,ret) ;
}本教程似乎表明,第二个版本也是TCO,但是第二个版本返回的最后一个内容是undefined,根据本教程的说法,它的调用不在尾部位置。
但是,这里似乎根本没有使用return,因此没有必要在堆栈上创建一个新的框架,并返回到的地址。这就是第二次实施TCO的原因吗?
发布于 2017-04-10 09:05:06
带有Node7的--harmony_tailcalls并不认为第二个对TCO有效,但是TCO在V8中还没有100%完成(因此在运行时标志后面)。
Axel 说不,这不是尾声,因为它后面有一个隐式return undefined:
以下代码中的函数调用
bar()不在尾位置: 函数foo() { bar();//这不是JS }中的尾调用。 原因是foo()的最后一个操作不是函数调用bar(),而是(隐式)返回undefined。换句话说,foo()的行为如下: 函数foo() { bar();返回未定义的;} 调用者可以依赖foo(),始终返回undefined。如果bar()由于尾部调用优化而返回foo()的结果,那么这将改变foo的行为。
换句话说,在foo的末尾,我们不能直接跳到bar,因为bar可能发出一个值而不是undefined,而foo根本不返回任何值(因此调用它可以保证产生undefined)。当我们调用bar说“但不要返回bar的返回值”时,有些东西必须留下来(至少现在是这样)。
理论上,JavaScript引擎在调用bar时可以传递某种标志,告诉自己丢弃任何值bar返回,因此在这种情况下允许TCO,但我在规范中没有看到这样做的任何东西。
https://stackoverflow.com/questions/43317853
复制相似问题