这个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 === undefined
为typeof 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这样的库可以做到这一点)。
其他人解释undefined
。 undefined
就像一个全局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; })();
但是,如果您将window
variables作为参数,则不存在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次迭代中甚至没有一个毫秒。 这简直是无用的。