有些同事说嵌套功能对性能不利,我想问一下这个问题。
让我说我有这个功能:
function calculateStuff() {
function helper() {
// helper does things
}
// calculateStuff does things
helper();
}
helper是一个私有函数,仅在calculateStuff中使用。这就是为什么我想把它封装在calculateStuff中。
这比表现更差吗?
function helper() {
}
function calculateStuff() {
helper();
}
请注意,在第二种情况下,我将助手暴露给我的范围。
答案 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();
}
})();