这个javascript/jquery语法是如何工作的: (function( window, undefined ) { })(window)?

How does this JavaScript/JQuery Syntax work: (function( window, undefined ) { })(window)?

您是否曾经查看过jquery 1.4源代码,并注意到它是如何以以下方式封装的:

1
2
3
4
5
6
(function( window, undefined ) {

  //All the JQuery code here
  ...

})(window);

我读过一篇关于javascript名称空间的文章,还有一篇叫做"一对重要的parens"的文章,所以我知道这里发生了什么。

但我以前从未见过这种特殊的语法。那埃多克斯1〔0〕在那里干什么?为什么需要通过EDOCX1[1]然后再次出现在结尾?


未定义是一个正态变量,可以简单地用undefined ="new value";来更改。所以jquery创建了一个真正未定义的本地"未定义"变量。

由于性能原因,窗口变量被设置为本地变量。因为当javascript查找变量时,它首先遍历局部变量,直到找到变量名。当找不到它时,javascript将进入下一个作用域等,直到它过滤掉全局变量。因此,如果将窗口变量设为本地变量,则javascript可以更快地查找它。更多信息:加速你的javascript-尼古拉斯C.扎卡斯


未定义

通过声明undefined作为参数,但从不向其传递值,可以确保它始终是未定义的,因为它只是全局范围中可以被覆盖的变量。这使得a === undefined成为typeof a == 'undefined'的安全替代品,节省了一些字符。它还使代码更小型化,例如,可以将undefined缩短为u,从而节省更多的字符。

窗口

window作为参数传递会在本地作用域中保留一个副本,这会影响性能:http://jspef.com/short-scope。到window的所有访问现在都必须在作用域链上减少一个级别。与undefined一样,本地拷贝再次允许更激进的缩小。

司扥噢特:

虽然jquery开发人员并不打算这样做,但是传入window可以使库更容易地集成到服务器端的javascript环境中,例如node.js,其中没有全局window对象。在这种情况下,只需更改一行就可以用另一行替换window对象。在jquery的情况下,可以创建一个模拟的window对象,并将其传递给HTML抓取(JSDOM之类的库可以这样做)。


其他人已经解释了undefinedundefined就像一个全局变量,可以重新定义为任何值。这项技术是为了防止所有未定义的检查被破坏,如果有人在某个地方写了,比如说,undefined = 10。无论变量undefined的值如何,一个从未通过的论点都保证是真实的undefined

通过以下示例可以说明通过窗口的原因。

1
2
3
4
5
6
7
(function() {
   console.log(window);
   ...
   ...
   ...
   var window = 10;
})();

控制台记录什么?window对象权的价值?错了!10?错了!它记录了undefined。javascript解释器(或jit编译器)以这种方式重写它-

1
2
3
4
5
6
7
8
9
10
(function() {
   var window; //and every other var in this function

   console.log(window);
   ...
   ...
   ...
   window = 10;

})();

但是,如果您得到window变量作为参数,那么就没有var,因此也没有惊喜。

我不知道jquery是否在这样做,但是如果您出于任何原因在函数的任何地方重新定义window局部变量,那么从全局范围借用它是一个好主意。


当有人决定在IE中重新定义窗口对象时,window就这样传入,我假设undefined也是这样,以防以后以某种方式重新分配。

该脚本中顶部的window只是命名参数"window",这个参数在全局window引用时更为局部,并且它将使用这个闭包中的代码。最后的window实际上是为第一个论点指定要通过什么,在这种情况下,window的当前含义……希望你在这之前没有搞砸window

通过显示jquery中使用的最典型的情况,plugin .noConflict()处理,这可能更容易理解,因此对于大多数代码,您仍然可以使用$,即使它意味着除jQuery之外的其他内容:

1
2
3
(function($) {
  //inside here, $ == jQuery, it was passed as the first argument
})(jQuery);


用1000000次迭代进行测试。这种本地化对性能没有影响。在1000000次迭代中甚至没有一毫秒。这根本没用。