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

你有没有在JQuery 1.4的源代码下看看,注意到它是如何封装在以下的方式:

(function( window, undefined ) { //All the JQuery code here ... })(window); 

我已经阅读了关于JavaScript命名空间的一篇文章,以及另一篇名为“ 一对重要的父母 ”的文章,所以我知道一些关于这里发生的事情。

但是我从来没有见过这个特殊的语法。 那里有什么undefined事情呢? 为什么window需要通过,然后再出现在最后?

undefined是一个正常的variables,可以用undefined = "new value";来简单的改变undefined = "new value"; 。 所以jQuery创build一个本地的“未定义”的variables是真正的未定义的。

出于性能原因,窗口variables是本地的。 因为当JavaScript查找一个variables时,它首先通过局部variables,直到findvariables名称。 当没有find时,JavaScript会遍历下一个范围,直到它通过全局variables进行过滤。 所以,如果窗口variables是本地的,JavaScript可以更快地查找它。 更多信息: 加速您的JavaScript – Nicholas C. Zakas

未定义

通过声明undefined为参数,但不传递值来确保它始终未定义,因为它只是全局范围中的一个variables,可以被覆盖。 这使得a === undefinedtypeof a == 'undefined'的安全替代scheme,它可以节省几个字符。 它也使代码更加友好,因为undefined可以缩短为u ,例如保存更多的字符。

窗口

window作为parameter passing会保留本地作用域中的副本,从而影响性能: http : //jsperf.com/short-scope 。 所有对window访问现在必须在范围链上less一级。 与undefined ,本地副本再次允许更积极的缩小。


边注:

虽然这可能不是jQuery开发人员的意图,但传入window允许将库更容易地集成到服务器端的Javascript环境中,例如node.js (其中没有全局window对象)。 在这种情况下,只需要更改一行来replace另一个window对象。 在jQuery的情况下,可以创build一个模拟window对象,并将其传递给HTML抓取(像jsdom这样的库可以做到这一点)。

其他人解释undefinedundefined就像一个全局variables,可以重新定义为任何值。 这个技巧是为了防止所有未定义的检查破坏,如果有人写, undefined = 10地方。 不论variables undefined的值如何,一个永远不会被传递的参数保证是真实的undefined

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

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

控制台logging什么? window对象的值是否正确? 错误! 10? 错误! 它的日志undefined 。 Javascript解释器(或JIT编译器)以这种方式重写它 –

 (function() { var window; //and every other var in this function console.log(window); ... ... ... window = 10; })(); 

但是,如果您将windowvariables作为参数,则不存在var,因此不会有任何意外。

我不知道jQuery是否正在这样做,但是如果你正在函数的任何地方重新定义window局部variables,无论出于何种原因,从全局范围借用它是一个好主意。

window是这样传递的,以防万一有人决定在IE中重新定义窗口对象,我假定undefined的相同,以防以后重新分配。

该脚本中的顶部window只是命名参数“窗口”,这是一个更本地化的参数,全局window引用以及这个闭包内部的代码将使用什么。 最后的window实际上是指定为第一个parameter passing什么,在这种情况下window的当前含义…希望是在这种情况发生之前,你还没有搞砸window

通过显示jQuery中使用的最典型的例子,插件.noConflict()处理,可以更容易地想到,因此对于大多数代码,仍然可以使用$ ,即使它在此范围之外意味着除jQuery外的其他内容

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

testing1000000次迭代。 这种本地化对性能没有影响。 在1000000次迭代中甚至没有一个毫秒。 这简直是​​无用的。