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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2716069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:36:41  来源:igfitidea点击:

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

javascriptjquerysyntax

提问by dkinzer

Have you ever taken a look under the hood at the jQuery 1.4source code and noticed how it's encapsulated in the following way:

您是否曾深入了解jQuery 1.4源代码,并注意到它是如何以下列方式封装的:

(function( window, undefined ) {

  //All the JQuery code here 
  ...

})(window);

I've read an article on JavaScript Namespacingand another one called "An Important Pair of Parens," so I know some about what's going on here.

我读过一篇关于JavaScript 命名空间的文章和另一篇名为“一对重要的括号”的文章,所以我对这里发生的事情有所了解。

But I've never seen this particular syntax before. What is that undefineddoing there? And why does windowneed to be passed and then appear at the end again?

但我以前从未见过这种特殊的语法。那undefined在那里做什么?为什么window需要通过然后再次出现在末尾?

回答by Vincent

The undefined is a normal variable and can be changed simply with undefined = "new value";. So jQuery creates a local "undefined" variable that is REALLY undefined.

undefined 是一个普通变量,可以简单地使用undefined = "new value";. 因此,jQuery 创建了一个本地“未定义”变量,该变量实际上是未定义的。

The window variable is made local for performance reasons. Because when JavaScript looks up a variable, it first goes through the local variables until it finds the variable name. When it's not found, JavaScript goes through the next scope etc. until it filters through the global variables. So if the window variable is made local, JavaScript can look it up quicker. Further information: Speed Up Your JavaScript - Nicholas C. Zakas

出于性能原因,窗口变量是本地的。因为当 JavaScript 查找一个变量时,它首先会遍历局部变量,直到找到变量名。如果没有找到,JavaScript 会遍历下一个范围等,直到它过滤全局变量。因此,如果将 window 变量设为本地变量,JavaScript 可以更快地查找它。更多信息:加速你的 JavaScript - Nicholas C. Zakas

回答by David Tang

Undefined

不明确的

By declaring undefinedas an argument but never passing a value to it ensures that it is always undefined, as it is simply a variable in the global scope that can be overwritten. This makes a === undefineda safe alternative to typeof a == 'undefined', which saves a few characters. It also makes the code more minifier-friendly, as undefinedcan be shortened to ufor example, saving a few more characters.

通过声明undefined为参数但从不向其传递值可确保它始终未定义,因为它只是全局范围内可以被覆盖的变量。这是a === undefined一个安全的替代方案typeof a == 'undefined',可以节省几个字符。它还使代码对压缩器更加友好,例如undefined可以缩短u为节省更多字符。

Window

窗户

Passing windowas an argument keeps a copy in the local scope, which affects performance: http://jsperf.com/short-scope. All accesses to windowwill now have to travel one level less up the scope chain. As with undefined, a local copy again allows for more aggressive minification.

window作为参数传递在本地范围内保留一个副本,这会影响性能:http: //jsperf.com/short-scopewindow现在,所有对 的访问都必须在作用域链上少上一层。与 一样undefined,本地副本再次允许更积极的缩小。



Sidenote:

边注:

Though this may not have been the intention of the jQuery developers, passing in windowallows the library to be more easily integrated in server-side Javascript environments, for example node.js- where there is no global windowobject. In such a situation, only one line needs to be changed to replace the windowobject with another one. In the case of jQuery, a mock windowobject can be created and passed in for the purpose of HTML scraping (a library such as jsdomcan do this).

虽然这可能不是 jQuery 开发人员的意图,但传入window允许库更容易地集成到服务器端 Javascript 环境中,例如node.js- 那里没有全局window对象。在这种情况下,只需更改一行即可将window对象替换为另一行。在 jQuery 的情况下,window可以创建一个模拟对象并传入以进行 HTML 抓取(jsdom 之类的库可以做到这一点)。

回答by Chetan Sastry

Others have explained undefined. undefinedis like a global variable that can be redefined to any value. This technique is to prevent all undefined checks from breaking if someone wrote say, undefined = 10somewhere. An argument that is never passed is guaranteed to be real undefinedirrespective of the value of the variableundefined.

其他人已经解释过了undefinedundefined就像一个全局变量,可以重新定义为任何值。这种技术是为了防止所有未定义的检查在有人写到undefined = 10某处时被破坏。undefined无论变量的值如何,从不传递的参数都保证是真实的undefined

The reason to pass window can be illustrated with the following example.

传递窗口的原因可以用下面的例子来说明。

(function() {
   console.log(window);
   ...
   ...
   ...
   var window = 10;
})();

What does the console log? The value of windowobject right? Wrong! 10? Wrong! It logs undefined. Javascript interpreter (or JIT compiler) rewrites it this way -

控制台记录什么?window对象的值吧?错误的!10?错误的!它记录undefined。Javascript 解释器(或 JIT 编译器)以这种方式重写它 -

(function() {
   var window; //and every other var in this function

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

})();

However, if you get the windowvariable as an argument, there is no var and hence no surprises.

但是,如果您将window变量作为参数,则没有 var,因此不会有任何意外。

I don't know if jQuery is doing it, but if you are redefining windowlocal variable anywhere in your function for whatever reason, it is a good idea to borrow it from global scope.

我不知道 jQuery 是否正在这样做,但是如果您window出于任何原因在函数中的任何位置重新定义局部变量,最好从全局范围借用它。

回答by Nick Craver

windowis passed in like that just in case someone decides to redefine the window object in IE, I assume the same for undefined, in case it's re-assigned in some way later.

window就像这样传入,以防万一有人决定在 IE 中重新定义 window 对象,我假设相同的undefined,以防以后以某种方式重新分配。

The top windowin that script is just naming the argument "window", an argument that's more local that the global windowreference and it what the code inside this closure will use. The windowat the end is actually specifying what to pass for the first argument, in this case the current meaning of window...the hope is you haven't screwed up windowbefore that happens.

window脚本的顶部只是将参数命名为“window”,该参数比全局window引用更局部,并且此闭包中的代码将使用它。将window在年底实际上指定什么传递的第一个参数,在这种情况下,目前的意义window......希望是你还没有搞砸了window在这之前发生。

This may be easier to think of by showing the most typical case used in jQuery, plugin .noConflict()handling, so for the majority of code you can still use $, even if it means something otherthan jQueryoutside this scope:

这可以通过显示在jQuery中使用的最典型的案例,插件想更容易.noConflict()处理,所以对于广大的代码,你仍然可以使用$,即使这意味着什么其他jQuery这个范围之内:

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

回答by Semra

Tested with 1000000 iterations. This kind of localization had no effect in performance. Not even a single millisecond in 1000000 iterations. This is simply useless.

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