为什么没有JavaScript引擎支持尾调用优化?

6

2
我认为ES6会提供它。 - ErikR
是的,我相信你是正确的。我更好奇的是为什么它现在才被添加为一个功能? - asloan
1
请查看这篇文章,了解尾调用优化的困难之处。是的,在 ES6 中一定会实现它。 - Mike Cluck
3
巨大的区别在于,在Haskell中,TCO是必要的,而在其他语言中,它只是一个特性,会增加编译器的复杂性。 - Bergi
此外,大量递归也会遇到默认情况下非常小的调用堆栈限制。我认为 JS(截至 ES5)过去并不是主要针对递归设计的。 - TaoPR
显示剩余2条评论
1个回答

9
Tail call优化在JavaScript中得到支持。目前还没有浏览器实现该功能,但随着规范(ES2015)的最终确定和所有环境都必须实现该功能。像BabelJS这样的转译器已经支持将新的JavaScript转换为旧的JavaScript,并且您今天就可以使用它。
Babel所做的翻译非常简单:
function tcoMe(x){
    if(x === 0) return x;
    return tcoMe(x-1)
}

被转换为:

function tcoMe(_x) {
    var _again = true;

    _function: while (_again) {
        var x = _x;
        _again = false;

        if (x === 0) return x;
        _x = x - 1;
        _again = true;
        continue _function;
    }
}

那就是——使用while循环。

至于为什么只有最近才支持这个功能,因为社区之前没有太大的需求。由于JavaScript是一种带有循环语句的命令式语言,所以在绝大多数情况下,您可以自己编写此优化(这与ML不同,在ML中,这是必需的,正如Bergi所指出的那样)。


你不是指机器语言吧? - Bergi
@Bergi 哈哈,不是的,我指的是ML,它是一系列语言,如OCaml和F#(直接方言)以及Haskell(带有非严格评估但相同思想的ML),尽管该语句对于其他函数式语言如scheme同样适用。 - Benjamin Gruenbaum
是的,这正是我所怀疑的,但复数让我感到困惑。我从未将ML称为语言“家族” :-) - Bergi
尾调用可以重复使用其封闭函数的堆栈帧(相同的返回点)。只需初始化内部变量,包括参数。这是否意味着,对于JS引擎而言,尾调用与命令式循环一样易于优化?通常我不关心微观优化,但当涉及迭代时... - user5536315
@IvenMarquardt 是的,可能尾调用与其他调用一样快。 - Benjamin Gruenbaum
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接