javascript 中的嵌套函数和性能?

Nesting functions and performance in javascript?

一些同事说嵌套函数对性能不利,我想问一下。

假设我有以下功能:

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

helper 是私有函数,只在calculateStuff 内部使用。这就是为什么我想将其封装在 calculateStuff 中。

这是否比做更糟糕的性能:

function helper() {

}

function calculateStuff() {
    helper();
}

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

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

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

如果你想在不污染外部作用域的情况下重用helper,你可以使用 IIFE:

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

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

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

无论如何,我们讨论的是每次迭代的纳秒级开销,因此除非您的代码执行得很多,否则您永远不会注意到时差。如有疑问,请对其进行分析并检查...


我决定听从我自己的建议,并使用 Safari 9 对此 on jsperf 进行分析。我使用了原始问题中提供的不执行任何操作的函数,以强调仅调用嵌套函数的开销:

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

平面函数:每秒 1,035,000,000 卡

:每秒 220,000,000 卡

很明显,平面函数比任何一个替代版本都快 很多。 但是,想一想这些数字的大小——即使是 "slow" 版本也只增加了 0.007 微秒的执行时间。如果您在该函数中进行任何类型的计算或 DOM 操作,它绝对会使嵌套函数的开销相形见绌。