您是否曾深入了解jQuery 1.4源代码,并注意到它是如何以下列方式封装的:
(function( window, undefined ) {
//All the JQuery code here
...
})(window);
我读过一篇关于JavaScript 命名空间的文章和另一篇名为“一对重要的括号”的文章,所以我对这里发生的事情有所了解。
但我以前从未见过这种特殊的语法。那undefined
在那里做什么?为什么window
需要通过然后再次出现在末尾?
您是否曾深入了解jQuery 1.4源代码,并注意到它是如何以下列方式封装的:
(function( window, undefined ) {
//All the JQuery code here
...
})(window);
我读过一篇关于JavaScript 命名空间的文章和另一篇名为“一对重要的括号”的文章,所以我对这里发生的事情有所了解。
但我以前从未见过这种特殊的语法。那undefined
在那里做什么?为什么window
需要通过然后再次出现在末尾?
undefined 是一个普通变量,可以简单地使用undefined = "new value";
. 因此,jQuery 创建了一个本地“未定义”变量,该变量实际上是未定义的。
出于性能原因,窗口变量是本地的。因为当 JavaScript 查找一个变量时,它首先会遍历局部变量,直到找到变量名。如果没有找到,JavaScript 会遍历下一个范围等,直到它过滤全局变量。因此,如果将 window 变量设为本地变量,JavaScript 可以更快地查找它。更多信息:加速你的 JavaScript - Nicholas C. Zakas
不明确的
通过声明undefined
为参数但从不向其传递值可确保它始终未定义,因为它只是全局范围内的一个可以被覆盖的变量。这是a === undefined
一个安全的替代方案typeof a == 'undefined'
,可以节省几个字符。它还使代码对压缩器更加友好,例如undefined
可以缩短u
为节省更多字符。
窗户
window
作为参数传递在本地范围内保留一个副本,这会影响性能:http : //jsperf.com/short-scope。window
现在,所有对 的访问都必须在作用域链上少上一层。与 一样undefined
,本地副本再次允许更积极的缩小。
边注:
虽然这可能不是 jQuery 开发人员的意图,但传入window
允许库更容易地集成到服务器端 Javascript 环境中,例如node.js - 那里没有全局window
对象。在这种情况下,只需更改一行即可将window
对象替换为另一行。在 jQuery 的情况下,window
可以创建一个模拟对象并传入以进行 HTML 抓取(像jsdom这样的库可以做到这一点)。
其他人已经解释过了undefined
。undefined
就像一个全局变量,可以重新定义为任何值。这种技术是为了防止所有未定义的检查在有人写到undefined = 10
某处时被破坏。undefined
无论变量 的值如何,从不传递的参数都保证是真实的undefined
。
传递窗口的原因可以用下面的例子来说明。
(function() {
console.log(window);
...
...
...
var window = 10;
})();
控制台记录什么?window
对象的值吧?错误的!10?错误的!它记录undefined
。Javascript 解释器(或 JIT 编译器)以这种方式重写它 -
(function() {
var window; //and every other var in this function
console.log(window);
...
...
...
window = 10;
})();
但是,如果您将window
变量作为参数,则没有 var,因此不会出现意外。
我不知道 jQuery 是否正在这样做,但是如果您window
出于任何原因在函数中的任何位置重新定义局部变量,最好从全局范围借用它。
window
就像这样传入,以防万一有人决定在 IE 中重新定义 window 对象,我假设同样的 for undefined
,以防以后以某种方式重新分配。
该window
脚本的顶部只是将参数命名为“window”,该参数比全局window
引用更局部,并且此闭包中的代码将使用它。将window
在年底实际上指定什么传递的第一个参数,在这种情况下,目前的意义window
......希望是你还没有搞砸了window
在这之前发生。
这可以通过显示在jQuery中使用的最典型的案例,插件想更容易.noConflict()
处理,所以对于广大的代码,你仍然可以使用$
,即使这意味着什么其他比jQuery
这个范围之内:
(function($) {
//inside here, $ == jQuery, it was passed as the first argument
})(jQuery);
经过 1000000 次迭代测试。这种本地化对性能没有影响。在 1000000 次迭代中甚至没有一毫秒。这根本没用。