简体   繁体   中英

Issue with let keyword

I was playing with some code and ran into a situation where I couldn't identify why 'let' is behaving the way it does.

For the below block of code:

 var x = 20; // global scope function f() { let x = x || 30; } f(); // VM3426:1 Uncaught ReferenceError: x is not defined(…) 

I get the error 'x is not defined' on executing f(). I do understand 'let' variables are not hoisted but since 'x' has a global copy, why isn't the line inside function 'f' defaulting to global copy instead of throwing an error? Does 'let' set the variable to undeclared (instead of 'undefined' with var because of hoisting) at the beginning of the function? Is there any way to get the global copy of 'x' within the function?

The exception is about the right side x - when you are initializing block-scope x variable the global one is already "forgotten" however the new one is still not being declared and cannot be used during initialization

Compare with explicit calling global one

    function f() {
      let x = window.x || 30;
    }

Also take a look at this MDN article about let dead zones

let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used. This is unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope.

Here in your case, an exception is thrown because you are defining let with the same name.

For More Info

The declaration of the local x is shadowing the global one and new one is still not declared first and cannot be used during initialization. It is same situation like following :

 var foo = 5;
    function do_something() {
      console.log(foo); // ReferenceError
      let foo = 2;
    }
  do_something();

For reference MDN

As suggested by @m.antkowicz you can use window.x in your case.

you can use this keyword to access global scope

var x= 20; // global scope
 function f() { 
  let x =this.x || 30;    
}
f(); 

but In strict mode this will default undefined

Read it https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/this

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