Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript中的嵌套函数和性能?_Javascript_Performance_Nested Function - Fatal编程技术网

javascript中的嵌套函数和性能?

javascript中的嵌套函数和性能?,javascript,performance,nested-function,Javascript,Performance,Nested Function,一些同事说嵌套函数不利于性能,我想问一下这一点 假设我有以下功能: function calculateStuff() { function helper() { // helper does things } // calculateStuff does things helper(); } helper是一个私有函数,仅在calculateStuff中使用。这就是为什么我想把它封装在calculateStuff中 这是否比执行以下操作更糟糕: fun

一些同事说嵌套函数不利于性能,我想问一下这一点

假设我有以下功能:

function calculateStuff() {
    function helper() {
    // helper does things
    }
    // calculateStuff does things
    helper();
}
helper是一个私有函数,仅在calculateStuff中使用。这就是为什么我想把它封装在calculateStuff中

这是否比执行以下操作更糟糕:

function helper() {

}

function calculateStuff() {
    helper();
}

请注意,在第二种情况下,我将帮助程序公开到我的作用域。

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

对于第二个代码,所有调用将共享相同的
帮助程序
,但它会污染外部作用域

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

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

从理论上讲,这可能会对性能产生影响,因为每次调用calculateStuff时都需要为helper创建一个新的闭包上下文(因为它可能引用封闭范围中的变量)

我非常确信,大多数JavaScript引擎中的JIT编译器应该能够判断您实际上没有从父上下文访问任何变量,而只是跳过绑定所有这些值。我可能遗漏了一些边缘案例,在这些案例中,这通常是不可能的,但这似乎已经足够严格了

在任何情况下,我们讨论的都是每次迭代的纳秒开销,因此除非您的代码被大量执行,否则您永远不会注意到时间差。如果有疑问,请对其进行配置并检查


我决定听从自己的建议,用Safari 9来描述这一点。我使用了原始问题中提供的“不做任何事情”函数,以强调仅调用嵌套函数的开销:

function calculateStuff() {
    function helper() {
    // helper does things
    }
    // calculateStuff does things
    helper();
}
嵌套函数:每秒136000000次调用

平板功能:1035000000卡/秒

:220000000卡/秒


显然,平面函数比任何一种替代版本都要快得多。然而,想想这些数字的大小——即使是“慢”版本也只会增加0.007微秒的执行时间。如果在该函数中执行任何类型的计算或DOM操作,都会大大降低嵌套函数的开销。

您仍然会污染外部范围,虽然它不是全局作用域。@MinusFour究竟用什么污染它?@MinusFour它创建了一个中间作用域并污染了它,而不是外部作用域。我只是说中间作用域也可以被视为外部作用域(至少从匿名函数上下文来看)。@MinusFour这毫无意义。“每次调用calculateStuff时为helper创建一个新的闭包上下文(因为它可能引用封闭范围中的变量)。“---因此,如果它不涉及任何自由变量,那么根本就没有这种影响?如果这是您试图表达的,那么它是错误的。@zerkms:是的,如果它不引用自由变量,特别是如果它不是从该范围导出的,那么函数可以并且将被内联。“怎么回事?”虫族:我和马克都没这么说。当然,该标准对性能没有任何要求(ES5映射和集除外),但Mark是对的,大多数JIT编译器(即实际实现)能够跳过在堆上创建函数对象甚至闭包上下文。@Bergi是对的,但这意味着绑定词法作用域是唯一的开销。而函数的创建一般来说并不便宜。因此,我在这里的观点是,答案强调了作用域的绑定,而忽略了创建函数对象的一个重要部分。@zerkms:在任何情况下,答案都应该是“如果有疑问,请分析它”单独:-)我投票结束这个问题,因为性能指标最好由jsperf处理,并且随着浏览器的发展,保存期很短。不要询问其他人关于性能的问题。如果有疑问,请测量它。