5

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?

Adarsh Konchady
  • 2,577
  • 5
  • 30
  • 50
  • Possible duplicate of ["let" keyword vs "var" keyword in Javascript](http://stackoverflow.com/questions/762011/let-keyword-vs-var-keyword-in-javascript) – ozil Nov 10 '16 at 09:25
  • 1
    The declaration of the local `x` is shadowing the global one, but as you are assigning a value based on an existing `x`, the compliler cannot find one as one is shadowed and other one is not still declared. – Pablo Lozano Nov 10 '16 at 09:34

4 Answers4

5

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

m.antkowicz
  • 13,268
  • 18
  • 37
0

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

Gaurav joshi
  • 1,743
  • 1
  • 14
  • 28
0

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.

Mandeep Singh
  • 1,287
  • 14
  • 34
0

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

User
  • 1,334
  • 5
  • 29
  • 61