从函数调用返回值时,最新的 JavaScript/ECMAScripte 编译器是否优化了不必要的变量赋值?

Do the most current JavaScript/ECMAScripte compilers optimize out unnecessary variable assignment when returning the value from a function call?

假设我们在一个实现文件处理的对象中。我想编写代码以便于阅读。

很难分辨 return 类型的代码示例,尤其是在有多个嵌套函数调用时:

function create() {
    return doCreateAction();
}

这个例子通过引入一个澄清变量更具可读性:

function create() {
    var fileHandle = doCreateAction();
    return fileHandle;
}

理论上,第二个版本可以执行相同的操作,因为无论如何编译器都必须临时存储 doCreateAction() 的结果(可能在一些 hiddenm、匿名、短暂的临时变量中)。分配给命名变量时,这段代码会变慢吗?

我会说要么他们确实优化了变量,要么不值得打扰;在任何一种情况下,你都有更大的鱼要炸。 :-) 但是关于尾调用有一个有趣的方面。

但首先,就简单的性能而言:根据经验,this simplistic, synthetic test 表明函数的性能不会因是否存在变量而变化。另请注意,如果您使用合适的缩小器,缩小器可能会在 JavaScript 引擎查看之前为您删除该变量。

继续尾调用:如您所知,从 ES2015 开始,在严格模式下,规范要求 尾调用优化 (TCO),这意味着当函数 A return 是调用函数 B 的结果,而不是让 B return 将其结果传递给 A 然后 return 将其传递给调用者,A 将控制权直接传递给 B 然后 returns 结果给调用者。这在几个方面更有效(避免在堆栈上创建另一个帧,避免跳转)。

现在,这可能无关紧要,因为 JavaScript 引擎中 TCO 的开发即使没有死,至少也停滞了。 V8 团队开发了早期版本但放弃了,SpiderMonkey 也没有;据我所知,Safari 中只有 JavaScriptCore 会产生 TCO。但是,如果我 read the spec 正确(绝非易事),您的第一个示例在尾部位置有 doCreateAction,因此可以通过 TCO 进行优化,但您的第二个示例没有。

所以在这方面可能会有影响,如果以及何时广泛实施 TCO,如果在这种情况下实施 稍微 超出规范,其中显然,它实际上是尾调用。


我以前对在那种情况下使用变量进行调试相当严格; Chrome 的 devtools 的较新版本使得它对于 的目的是不必要的(当然,无论如何,一个 minifier 都会删除它):如果你进入 return,您会在变量的局部作用域列表中看到 return 值。当然,这只有在您使用 Chrome 的开发工具时才有用(例如,Firefox 的 [还没有?])。