在JavaScript函数中名为“undefined”的参数的用途是什么?

What is the purpose of a parameter named “undefined” in a JavaScript function?

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

1
2
3
(function( window, undefined)  {
  ...code here
})( window );


这是做什么的,是在该闭包内重新分配undefinedundefined。这是一个失败的安全措施。因为其他代码可能会意外地做类似的事情

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

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

引自MDN New_in_JavaScript 1.8.5(ECMA 5)页面

Changes to global objects

Global objects made read only

The NaN, Infinity, and undefined global
objects have been made read only, per the ECMAScript 5 specification.

来自Guthub的ES5 Annotated Spec

ES5 spec Section x15.1.1.3

15.1.1.3 undefined

The value of undefined is undefined (see 8.1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

即使global undefined不可写也可以使用名为undefined的局部变量,并且可能会破坏您的代码(主要是与undefined进行比较)。但这是你的责任。你可以有像这样的代码

1
2
3
4
5
6
7
8
9
10
(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创建的许多comparison,因为undefined不再是undefined。它现在有一些价值。

因此他们正在调用匿名函数之类的

1
( window ) // one argument only

并接受

1
2
3
4
5
( 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),undefined(value)和undefined(variable)。

未定义(类型)是内置的JavaScript类型。

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

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

没有return语句的函数或带有返回语句的函数返回undefined。未定义的函数参数的值未定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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),因为它是一个全局属性,我们也可以将它作为变量访问。为了保持一致性,我总是在本文中将其称为变量。

1
2
3
4
typeof undefined; //"undefined"
var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined"

从ECMA 3开始,可以重新分配其值:

1
2
3
4
5
undefined ="washing machine"; //assign a string to undefined (variable)
typeof undefined //"string"
f = undefined;
typeof f; //"string"
f; //"washing machine"

毋庸置疑,将值重新分配给未定义的变量是非常糟糕的做法,事实上ECMA 5不允许这样做。


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

您可以通过执行undefined = whatever创建一个覆盖未定义值的模块。

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

1
2
3
(function(window, undefined) {
    // undefined is the undefined parameter
}(window));

这是安全的,因为undefined参数在本地范围内,除了此函数中的代码之外没有人可以分配给它。

定义匿名函数时,不必使用undefined作为参数。

如果您看到上面的功能,您会注意到它需要两个参数但只提供一个参数。

为什么undefined需要恢复?

因为,要确保undefined在大括号之间的范围内确实是undefined,即使有人在全局范围内编写了类似undefined ="defined";的内容,因为实际上可以重新定义undefined

所以,如果你有类似的东西

1
2
3
4
5
var undefined = 1;

(function(window, undefined) {
  console.log(undefined); // output will be undefined not 1
}(window));


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

例如,当undefined实际上未定义时,请使用此代码:

1
2
var undefined = 1;
alert(undefined); // 1