请问一下 js递归的优化(尾递归的问题)

js尾递归优化

看阮一峰老师的es6教程,尾递归的时候有一样不明白

相关代码

function tco(f) {
            var value;
            var active = false;
            var accumulated = [];
            return function accumulator() {
                accumulated.push(arguments);
                if (!active) {
                    active = true;
                    while (accumulated.length) {
                        value = f.apply(this, accumulated.shift());
                        console.log(value)
                    }
                    active = false;
                    return value;
                }
            };
        }

        var sum = tco(function (x, y) {
            if (y > 0) {
                return sum(x + 1, y - 1)
            } else {
                return x
            }
        });

        console.log(sum(1, 3))

请问一下变量 value (不是最后一次的时候)为什么会等于undefined

阅读 3.4k
3 个回答

value = f.apply(this, accumulated.shift());
...


function(x, y) {
      if (y > 0) {
            return sum(x + 1, y - 1)//undefined
       }
            ...
}

其中f是下面的function,而sum(x + 1, y - 1)undefined,如果你要return

    return function accumulator() {
        if (!active) {
            ...
        }
        return 'return data here'
    };

active阻断了,当递归调用f的时候,

function accumulator() {
    accumulated.push(arguments); // 这个会执行,后续 while (accumulated.length)则为true
    // active为true,后面都不执行,返回值就是undefined
    if (!active) {
        active = true;
        ...

这个应该是仿尾调用吧,每次通过active清除调用栈,不过现在Node8+已经不再有尾调用了

这篇文章太老了,不要再纠结这个问题了。

虽然在 Node6、Node7 中可以使用命令行参数 --harmony-tailcalls 开启尾递归优化功能。但是这个特性已经被 V8 移除了,对应的 Node8 之后的版本都已经没有了尾递归优化功能。

在 Chrome 之前的某些版本确实可以通过 chrome://flags/#enable-javascript-harmony 开启,但是也已经被移除了。

因为尾递归优化会破坏函数的调用栈信息,TC39 也正在寻找新的 js 语法来显式指明需要使用尾递归优化。

据我刚才的测试结果,Firefox、Chrome、Node.js 都不支持,其他引擎没有测试,我猜应该也都已经去掉了对尾递归优化的支持。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题