在javascript中嵌套函数和性能?

use*_*969 10 javascript performance nested-function

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

让我们说我有这个功能:

function calculateStuff() {
    function helper() {
    // helper does things
    }
    // calculateStuff does things
    helper();
}
Run Code Online (Sandbox Code Playgroud)

helper是一个私有函数,仅在calculateStuff中使用.这就是我想在calculateStuff中封装它的原因.

这比表现更糟糕吗?

function helper() {

}

function calculateStuff() {
    helper();
}
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*sey 10

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

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

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


我决定遵循自己的建议,并使用Safari 9 在jsperf上对其进行分析.我使用了原始问题中提供的do-nothing函数,以突出显示调用嵌套函数的开销:

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

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

Oriol的IIFE版本:每秒220,000,000 卡路里

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

  • @zerkms:在任何情况下,答案都应该被赞成为"*如果有疑问,可以单独描述它":-) (2认同)

Ori*_*iol 5

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

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

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

var calculateStuff = (function () {
  function helper() {
    // helper does things
  }
  return function() {
    // calculateStuff does things
    helper();
  }
})();
Run Code Online (Sandbox Code Playgroud)

  • @MinusFour到底用什么污染了它? (2认同)
  • @MinusFour 这没有任何意义。 (2认同)