【问题标题】:What is the purpose of a parameter named "undefined" in a JavaScript function?JavaScript 函数中名为“未定义”的参数的目的是什么?
【发布时间】:2012-06-25 09:48:45
【问题描述】:

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

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

【问题讨论】:

标签: javascript undefined


【解决方案1】:

这样做是在闭包内将undefined 重新分配给undefined。那是一个故障保险。因为其他代码可能会不小心做类似的事情

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) 页面

对全局对象的更改

全局对象设为只读

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

来自 Guthub 的 ES5 Annotated Spec

ES5 spec Sectionx15.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 是可写的,那么上面的赋值可能会妨碍在该代码行之后使用undefined 生成的许多comparison,因为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

关于这个http://javascriptweblog.wordpress.com/2010/08/16/understanding-undefined-and-preventing-referenceerrors/的一篇很好的详细文章

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

什么是未定义的?

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

未定义(类型)是内置的 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 不允许这样做。

【讨论】:

  • console.log(undefined) .. 与否?是的,就像那样:)
  • 所以,例如,如果我在匿名函数之外有“var undefined = 1”,并且我有一个看起来像这样的匿名函数: (function( window, undefined ){ })(window) ;...你是说 undefined=1 现在的值为 undefined 吗?
  • @JaPerk14,检查更新后的答案,我引用了文章中的一些内容,为了in-depth 的理解,我建议您阅读整篇文章。
  • @JaPerk14,如果你有undefined = 1;在全局范围内,如果您不使用 (function( window, undefined ){ })(window); undefined 在该函数内也将具有 1 的值(因为您更改了全局 undefined 变量)。这是不可取的,因为undefined 应该是undefined。所以要确保在你的函数内部使用pattern
【解决方案2】:

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

您可以通过undefined = whatever 让模块覆盖 undefined 的值。

中的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));

【讨论】:

  • 你不解释为什么 undefined 需要恢复,其他答案可以。
【解决方案3】:

jQuery 确保 undefined 在其范围内确实是未定义的,方法是不将参数传递给该参数。

undefined 实际上不是未定义时,以这段代码为例:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    • 1970-01-01
    • 2021-11-15
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多