我一直在阅读"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
,即使它被全局覆盖。