在javascript中嵌套函数和性能?

时间:2015-10-20 23:04:30

标签: javascript performance nested-function

有些同事说嵌套功能对性能不利,我想问一下这个问题。

让我说我有这个功能:

function calculateStuff() {
    function helper() {
    // helper does things
    }
    // calculateStuff does things
    helper();
}

helper是一个私有函数,仅在calculateStuff中使用。这就是为什么我想把它封装在calculateStuff中。

这比表现更差吗?

function helper() {

}

function calculateStuff() {
    helper();
}

请注意,在第二种情况下,我将助手暴露给我的范围。

2 个答案:

答案 0 :(得分:10)

理论上,存在潜在的性能影响,因为每次调用 calculateStuff 时都需要为 helper 创建一个新的闭包上下文(因为它可能引用来自封闭范围)。

我非常确定大多数JavaScript引擎中的JIT编译器应该能够告诉您实际上没有从父上下文访问任何变量,只是跳过绑定所有这些值。我可能会遗漏一些通常不可能的边缘情况,但它似乎足够直接。

在任何情况下,我们都在谈论每次迭代的纳秒开销,所以除非您的代码执行很多,否则您永远不会注意到时差。如有疑问,请对其进行分析并检查......

我决定遵循自己的建议,并使用Safari 9对此on jsperf进行概要分析。我使用了原始问题中提供的无操作函数,以突出显示仅调用嵌套函数的开销: / p>

嵌套函数:每秒136,000,000次调用

平面功能:每秒1,035,000,000卡路里

Oriol's IIFE version:每秒220,000,000卡路里

显然,平面功能很多比任何一种替代版本都快。 然而,请考虑这些数字的大小 - 即使是“慢”版本也只会增加0.007微秒的执行时间。如果你在该函数中进行任何类型的计算或DOM操作,它绝对会使嵌套函数的开销相形见绌。

答案 1 :(得分:5)

使用您的第一个代码,每次调用calculateStuff时,都会创建helper的新副本。

使用第二个代码,所有调用将共享相同的helper,但它会污染外部范围。

如果要在不污染外部范围的情况下重用helper,可以使用IIFE:

var calculateStuff = (function () {
  function helper() {
    // helper does things
  }
  return function() {
    // calculateStuff does things
    helper();
  }
})();