19

在查看 jQuery 的未压缩源代码时,我偶然发现了一些我不太理解的东西。当创建他们的匿名函数时,他们将 undefined 作为第二个参数。这是在做什么,为什么他们使用 undefined?是否有必要将 undefined 作为参数放在匿名函数中?下面是我所说的一个例子。

(function( window, undefined)  {
  ...code here
})( window );
4

3 回答 3

20

这是在做什么,正在重新分配undefinedundefined该闭包内部。那是一个故障保险。因为其他代码可能会不小心做类似的事情

undefined = something;
console.log(undefined); // will output 'something'

这在 javascript 中是有效的(如果使用的 JS 引擎没有实现 ECMAScript 5 规范,在 ECMAScript 5 规范undefined中是非non-writableMDN DOC),

引用 MDN New_in_JavaScript 1.8.5 (ECMA 5) 页面

对全局对象的更改

全局对象设为只读

根据ECMAScript 5 规范,NaNInfinityundefined全局对象已设为只读。

来自ES5 Annotated SpecGuthub

ES5 spec Section x15.1.1.3

15.1.1.3 未定义

undefined 的值是 undefined(见 8.1)。

此属性具有属性 { [[Writable]]: false , [[Enumerable]]: false, [[Configurable]]: false }。

即使global 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是可写的,那么上面的分配可能会妨碍在该行代码之后进行的许多操作,因为comparison现在不再如此。它现在有一些价值。undefinedundefinedundefined

所以当他们调用那个匿名函数时

( 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在该匿名函数内部的使用。

关于此http://javascriptweblog.wordpress.com/2010/08/16/understanding-undefined-and-preventing-referenceerrors/的一篇非常详细的文章

我从上面的文章链接中引用了一些内容来说明问题

什么是未定义的?

在 JavaScript 中有未定义(类型)未定义(值)未定义(变量)。

Undefined (type)是一个内置的 JavaScript 类型。

undefined (value)是一个原始类型,是 Undefined 类型的唯一值。

任何尚未分配值的属性都假定为未定义的值。(ECMA 4.3.9 和 4.3.10)。

没有 return 语句的函数或带有空 return 语句的函数返回 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 (variable)是一个全局属性,其初始值为 undefined (value),由于它是一个全局属性,我们也可以将其作为变量访问。为了保持一致性,在本文中我总是将其称为变量。

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 不允许这样做。

于 2012-06-23T06:12:01.043 回答
3

Undefined 是一种类型,但也是一个全局变量。

您可以拥有一个通过执行覆盖 undefined 值的模块undefined = whatever

undefinedin 实际上是包装整个代码的函数的未定义参数:

(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));
于 2012-06-23T06:10:13.090 回答
2

undefinedjQuery通过不将参数传递给该参数来确保在其范围内确实是未定义的。

以这段代码为例,当undefined它实际上没有定义时:

var undefined = 1;
alert(undefined); // 1
于 2012-06-23T06:11:58.853 回答