使用`es2016`预设的Babel实现尾调用优化吗?

Mar*_*tus 6 javascript tail-recursion babeljs

我使用以下示例来测试使用Babel和es2016预设的尾调用递归:

'use strict';

try {
    function r(n) {
        if (n%5000===0)
            console.log(`reached a depth of ${n}`);
        r(n+1);
    }
    r(0);
} catch (e) {
    if (!(e instanceof RangeError))
        throw e;
    else
        console.log('stack blown');
}
Run Code Online (Sandbox Code Playgroud)

我的package.json档案是:

{
    "name": "tail-call-optimization",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "build": "babel es6 --out-dir es5 --source-maps",
        "watch": "babel es6 --out-dir es5 --source-maps --watch",
        "start": "node es5/app.js"
    },
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "babel-cli": "^6.6.5",
        "babel-core": "^6.7.4",
        "babel-loader": "^6.2.4",
        "babel-polyfill": "^6.7.4",
        "babel-preset-es2016": "^6.0.10",
        "babel-runtime": "^6.6.1"
    },
    "dependencies": {
        "babel-polyfill": "^6.7.4",
        "source-map-support": "^0.4.0"
    }
}
Run Code Online (Sandbox Code Playgroud)

...... .babelrc简单地说:

{
    "presets": ["es2016"]
}
Run Code Online (Sandbox Code Playgroud)

运行上面的:

npm run build && npm run start
Run Code Online (Sandbox Code Playgroud)

...导致以下控制台输出:

reached a depth of 0
reached a depth of 5000
reached a depth of 10000
reached a depth of 15000
stack blown
Run Code Online (Sandbox Code Playgroud)

实际上,查看es5目录中的已转换文件,没有任何迹象表明已经实现了TCO.

我错过了什么吗?

我的节点版本是4.3.2.

Mar*_*tus 6

看看:https://babeljs.io/docs/learn-es2015/一读:

暂时删除Babel 6

由于全局支持尾调用的复杂性和性能影响,仅支持显式自引用尾递归.由于其他错误而被删除并将重新实施.

所以我猜它目前还没有实现.


JMM*_*JMM 0

目前,“官方”Babel 6 插件/预设均未实现 TCO。babel-preset-es2016不是“官方”预设。除非 TCO 依赖于 Babylon 中的解析器支持(我不这么认为,但我不确定),那么我认为用户态插件/预设可以实现它,并且也许可以实现(但我不知道)的)。这是跟踪最终“官方”重新实施的问题:T2614。如果有人想将该链接公关到 Learn ES2015 文档 @Marcus 提到的 ping 我这里,我将合并它。