在 Javascript 中覆盖未定义和 IIFE



我一直在阅读"You Don't Know Js"系列,并遇到了这个:

"这种模式的另一个应用解决了(次要的(问题,即默认undefined标识符的值可能会被错误地覆盖,从而导致意外结果。通过将参数命名为undefined,但不为该参数传递任何值,我们可以保证undefined标识符实际上是代码块中的undefined值:">

undefined = true; // setting a land-mine for other code! avoid!
(function IIFE(undefined) {
var a;
if (a === undefined) {
console.log("Undefined is safe here!");
}
})();

我不明白这里发生了什么。未定义是数据类型还是只是标识符,此代码的工作原理是什么?

谢谢。

undefined(标识符(是一个预定义的全局变量,其值令人困惑的是,undefined,它是 Undefined 类型的唯一成员。(我不骗你。

过去undefined(标识符(不是只读的,您可以分配给它。这在很久以前就不再是真的了(2009 年,截至 ES5(;这记录undefined,而不是true

undefined = true;
console.log(undefined);

。但这就是该部分描述的"利基问题"。

在2018年,一个不同但真正的利基问题是,你可以遮蔽undefined标识符,并赋予它你想要的任何值:

(function() {
var undefined = true;
console.log(undefined); // true
})();

因此,如果您的代码可能被置于其他代码的中间,则您可能正在处理与全局标识符不同的undefined标识符。

因此,为了处理这种异常不太可能发生的情况,您可以编写隐藏undefined的代码,但使用正确的值,方法是使用将其声明为参数的 IIFE,然后不传入任何值;参数将接收的值将是实际值undefined

(function() {
var undefined = true;
//  ^---- a local variable that shadows (hides) the global
console.log(undefined); // true

(function(undefined) {
//        ^---- a parameter that shadows (hides) the one above
console.log(undefined); // undefined
})(); // <== Notice we aren't passing any argument for the parameter here
})();

由于我们不传递参数,因此参数接收undefined(无论undefined标识符在任何给定范围内可能持有什么值(。

尽管有命名,但使用没有移交值的函数参数是undefined的。

(function IIFE(undefined) {
})();          ^^^^^^^^^
^^ --------------+

undefined = true; // setting a land-mine for other code! avoid!
(function IIFE(undefined) {
var a;
if (a === undefined) {
console.log("Undefined is safe here!");
}
})();

如果参数没有命名为"undefined"(这不是工作所必需的(,也许更容易理解

undefined = true;
function f ( param ) {
console.log( 'Param is:', param )
}
f();
-> Param is: undefined

仍然可以访问函数内部的值undefined,即使它被全局覆盖。

最新更新