简体   繁体   中英

Overwriting undefined and IIFE in Javascript

I have been reading the "You Don't Know Js" series and came across this:

"Another application of this pattern addresses the (minor niche) concern that the default undefined identifier might have its value incorrectly overwritten, causing unexpected results. By naming a parameter undefined , but not passing any value for that argument, we can guarantee that the undefined identifier is in fact the undefined value in a block of code: "

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

I don't understand what's happening here. Is undefined a data type or just an identifier and how this code works?

Thanks.

undefined (the identifier) is a predefined global variable whose value is, confusingly, undefined , which is the only member of the type Undefined. ( I kid you not .)

It used to be that undefined (the identifier) wasn't read-only, and you could assign to it. That stopped being true a long time ago (2009, as of ES5); this logs undefined , not true :

 undefined = true; console.log(undefined);

...but that's the "niche concern" that section is describing.

A different , but genuine, niche concern here in 2018 is that you can shadow the undefined identifier and give it any value you want:

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

So if your code may be plopped in the middle of other code, you could be dealing with a different undefined identifer than the global one.

So , to deal with that exceptionally-unlikely occurrence, you can write code that shadows undefined , but with the correct value, by using an IIFE that declares it as a parameter, and then not passing in any value; the value the parameter will receive will be the actual value 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 })();

Since we don't pass a parameter, the parameter receives the value undefined (regardless of what value the undefined identifier might hold in any given scope).

The use of a parameter of a function without a handed over value is undefined , despite of the naming.

(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!"); } })();

Maybe it's easier to understand if the parameter isn't named “undefined” (which isn't necessary for this to work)

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

It was still possible to access the value undefined inside the function, even though it was globally overwritten.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM