将全局变量传递给自执行函数或"IIFE"的目的是什么?

21

我在旧版 JavaScript 中经常看到这种情况。

(function (w){

    w.bar = 'baz';

 })(window); 

以上的优势是什么,相较于......

(function(){

    window.bar = 'baz';

})(); 
同样适用于任何全局变量,或在IIFE之外定义的变量。

11
能够将全局对象放置于局部作用域中,可以提供更快的内部查找速度和更高的性能。 - Rayon
@Rayon 这应该是答案,而不是评论。 - smnbbrv
1
不同意@Rayon。OP只是在window对象上添加了一个变量(好吧,也许有几个,但数量很少),看起来速度差异可能不太重要。 - user949300
Alex和Yuriy:我的回答足够了吗?需要更多细节吗?我的回答往往比较简洁,如果您需要更多解释,请告诉我。 - user949300
2
让我们再等几天看看是否还有其他人提供意见,在时间窗口关闭之前接受答案。 - Alexander Mills
显示剩余3条评论
4个回答

14
  1. 明确表示您在函数中使用(并可能修改)全局变量。
  2. 允许您将来修改行为。也许您拥有一个用于单元测试的mockWindow,或者您正在使用Node.js而没有window,但是想要添加到globals变量中。

p.s. @Rayon提到的微不足道的性能增益在我看来是一个干扰项。


3

传递窗口是因为局部变量比全局变量更容易、更快速地访问...这可能会在性能上显示出轻微的差异。该方法在模块模式和/或依赖注入中非常方便。

示例

var moduleFirst = (function(){
    var name = "harry";
    return {
        firstparam : name
    }
})();
var moduleTwo = (function(x){
    console.log(x.firstparam);
})(moduleFirst)

输出结果将是:harry

当window被传递给IIFE时,它的所有公开方法都可以在一个本地变量中使用。


3
在实践中,您提供的示例没有太大(甚至没有)区别,但是从您实际查看的代码中,您可能已经过于简化了它。
在更现实的程序中,您将具有作用域和回调,这些回调会在事件循环中异步触发和运行,并且您将变量绑定到闭包中的特定实例 - 因此;
(function (w){
    setTimeout(function(){w.bar = 'baz';},100);
})(window); 
window = window2;

由于原始窗口绑定到 w,因此栏仍在原始窗口中设置 - 在哪里呢?

(function (){
    setTimeout(function(){window.bar = 'baz';},10);
})(window); 
window = window2;

由于代码执行时窗口绑定的方式是实例window2,因此它将在该实例窗口中设置。

在这个例子中,“window”是一个全局变量,但不管绑定变量的作用域如何,情况都是一样的。


2
通过将全局对象如window、document、$传递给IIFE(立即调用的函数表达式),可以通过减少作用域查找时间来提高性能。请记住,Javascript首先在本地作用域中查找属性,并一直向上链接到全局作用域。因此,在本地作用域中访问window对象可以减少查找时间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接