查看 jQuery 未压缩的源代码时,我遇到了一些不太理解的东西。当他们创建匿名函数时,他们将 undefined 作为第二个参数放置在函数参数列表中。这是做什么的?为什么要使用 undefined?在匿名函数中加上 undefined 参数是否是必需的?以下是一个示例,说明了我的问题。
(function( window, undefined) {
...code here
})( window );
查看 jQuery 未压缩的源代码时,我遇到了一些不太理解的东西。当他们创建匿名函数时,他们将 undefined 作为第二个参数放置在函数参数列表中。这是做什么的?为什么要使用 undefined?在匿名函数中加上 undefined 参数是否是必需的?以下是一个示例,说明了我的问题。
(function( window, undefined) {
...code here
})( window );
这段代码的作用是在闭包内将undefined
重新赋值给undefined
。 这是一种安全措施,因为其他代码可能会意外执行类似以下的操作:
undefined = something;
console.log(undefined); // will output 'something'
在JavaScript中是有效的(如果使用的JS引擎未实现ECMAScript 5规范,在ECMAScript 5规范中,undefined
是非non-writable
的,参见MDN DOC )。
引用自MDNJavaScript 1.8.5新特性(ECMA 5)页面
全局对象变更
全局对象只读
根据ECMAScript 5规范,NaN、Infinity和undefined 全局对象已经被设置为只读。
并且来自GitHub的ES5 Annotated Spec
ES5规范第
x15.1.1.3
15.1.1.3 undefined
undefined
的值是未定义的(请参阅8.1)。该属性具有以下特征:{ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。
即使全局undefined
不可写,您仍然可以拥有名为undefined
的本地变量,并可能搞乱您的代码(主要是与undefined
进行比较)。但这是您的责任。您可以编写如下代码:
(function(){
console.log('Second Case: ');
var undefined = 'Something';
console.log(undefined); // Will log `something`
var a ; // a is undefined
console.log(a === undefined); // false, as undefined is changed
// you might expect a === undefined will return true, but as
// `undefined` is changed it will return false.
console.log(a); // undefined
})();
演示: http://jsfiddle.net/joycse06/V4DKN/
然而,如果undefined
是可写的,则上述赋值可能会干扰在该代码行之后进行的许多与undefined
比较的操作,因为undefined
不再是undefined
。它现在具有某个值。
因此,他们正在像这样调用匿名函数:
( window ) // one argument only
我理解您需要的翻译是:
接收到
( window, undefined) // only window is passed when calling the function
// Second argument is not passed means it's undefined
// so undefined is restored to undefined inside that function
// and no global accidental assignments can hamper jQuery's
// code using 'undefined' now
那意味着在该闭包内部,undefined
被恢复为undefined
,因为它没有被传递任何值,从而保证在该匿名函数内部使用undefined
。var a;
typeof a; //"undefined"
window.b;
typeof window.b; //"undefined"
var c = (function() {})();
typeof c; //"undefined"
var d = (function(e) {return e})();
typeof d; //"undefined"
undefined (变量) 是一个全局属性,其初始值为 undefined (值)。由于它是一个全局属性,我们也可以将其视为变量进行访问。出于一致性考虑,在本文中我始终将其称为变量。
typeof undefined; //"undefined"
var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined"
从ECMA 3版本开始,它的值可以被重新赋值:
undefined = "washing machine"; //assign a string to undefined (variable)
typeof undefined //"string"
f = undefined;
typeof f; //"string"
f; //"washing machine"
不用说,重新分配未定义变量的值是非常糟糕的做法,事实上它在ECMA 5中是不允许的。
undefined = 1
;,那么如果你不使用 (function( window, undefined ){ })(window);
,那么在该函数内部,undefined
的值也将为 1
(因为你改变了全局的 undefined
变量)。这是不可取的,因为 undefined
应该是 undefined
。因此,为了确保在函数内部使用 pattern
。 - Prasenjit Kumar NagUndefined 是一种数据类型,但也是一个全局变量。
你可以创建一个模块来覆盖 undefined 的值:undefined = something
。
实际上,undefined
在这里是一个函数的未定义参数,它包装了整个代码:
(function(window, undefined) {
// undefined is the undefined parameter
}(window));
这是安全的,因为undefined
参数在局部作用域中,除了此函数中的代码以外,没有人可以对其进行赋值。
在定义匿名函数时,不必使用undefined
作为参数。
如果你看到上面的函数,你会注意到它希望有两个参数,但只提供了一个。
为什么需要还原undefined
?
因为要确保在花括号之间的作用域中undefined
确实是undefined
,即使有人在全局作用域中写入undefined = "defined";
,因为undefined
实际上可以被重新定义。
所以如果你有像下面这样的东西
var undefined = 1;
(function(window, undefined) {
console.log(undefined); // output will be undefined not 1
}(window));
jQuery通过不向该参数传递参数来确保其作用域内的undefined
确实未定义。
例如,当undefined
实际上并未被定义时,请参考以下代码:
var undefined = 1;
alert(undefined); // 1