我已经注意到jQuery
相关的主题插件,例如作为参数jQuery.UI
传递undefined
给在其module定义中使用的匿名函数,如下所示:
(function($, undefined) { ... })(jQuery);
或者,我注意到 jQuery 和/或其他人推荐的其他插件不会将 undefined 作为参数传递。
这可能是一个愚蠢的问题,但是......
无论如何它不应该总是可用吗?为什么要传进去?这里有什么其他目的或技巧吗?
我已经注意到jQuery
相关的主题插件,例如作为参数jQuery.UI
传递undefined
给在其module定义中使用的匿名函数,如下所示:
(function($, undefined) { ... })(jQuery);
或者,我注意到 jQuery 和/或其他人推荐的其他插件不会将 undefined 作为参数传递。
这可能是一个愚蠢的问题,但是......
无论如何它不应该总是可用吗?为什么要传进去?这里有什么其他目的或技巧吗?
有两个原因:
1) 如果undefined
是函数作用域中的变量而不是全局对象属性,压缩器可以将其缩减为单个字母,从而实现更好的压缩率。
2) 在 ES5* 之前,undefined
是没有写保护的全局对象的属性。所以它可能会被覆盖,导致奇怪和意外的行为。你可以这样做:
var test = 123;
undefined = 123;
if (test === undefined){
// this will actually be true, since undefined now equals 123
}
通过使用undefined
不向其传递参数的函数参数(名称实际上无关紧要),您可以确保您拥有一个真正存在的变量,undefined
以便您可以针对该变量测试“未定义性”。
顺便提一句。测试 undefined 的最安全方法是:typeof ( var ) === 'undefined'
(*)的ECMAScript 5,全球性undefined
,NaN
以及Infinity
只读成了。因此,随着它在所有现代浏览器中的普遍采用——当然,IE 9 除外——不再可能覆盖这些值。
这样做是为了确保 undefined 总是undefined
. 在旧版本的 ECMAScript 规范(ECMAScript 5 之前)中, undefined 不是保留字而是常规变量。在较旧的浏览器中,这将被允许,例如:
undefined = 2; // Assign a different value to undefined
// Now this statement would be true
if (undefined == 2)
所以为了确保 undefined 实际上是 undefined,即使其他一些“邪恶的”脚本会用另一个值重新分配 undefined,你创建一个你称之为 undefined 的参数,然后当你调用函数时,你确保不通过该参数的值 - 因此您可以确定未定义的变量在您的函数中将始终未定义。
所以在 jQuery 的情况下:
(function($, undefined) { ... })(jQuery);
为方便起见,他们传入 jQuery 并将其分配给 $ 变量,但随后他们不会将第二个值传递给 undefined 参数,因此 undefined 将是未定义的。
现代浏览器
在现代浏览器中,undefined
根据ECMAScript 5 规范是不可配置、不可写的属性。
undefined 不是 JavaScript 中的保留字,它只是一个变量。jQuery 确保如果一些糟糕的开发人员在他们的 javascript 中覆盖了 undefined 的值,那么 jQuery 将忽略它并建立它自己的变量 undefined,它永远不会传递值(请参阅最后的自执行 (jQuery))和因此实际上是未定义的。