Search code examples
javascriptvarlet

What does it mean to say let declarations are hoisted but not initialized?


I know that snippet below results in ReferenceError:

console.log(b);
let b = 3;

And i've read that it wouldn't fail if we were using var instead of let.
MDN documentations, claims that let declarations are hoisted too, but they are not initialized
What confuses me is that initialization, how can it even matter when we are talking about ReferenceError.

In the code below,

let b;
console.log(b);
b = 3;

initialization is written after the console.log(b) but this doesn't make any ReferenceError, so it doesn't make sense to say that in the first snippet exception is thrown because the variable is not initialized.

Could anyone please clarify these things please?


Solution

  • The let (and const) declaration will throw an error if accessed before initialized.

    What do that mean?

    You'll get an error if you try to access a variable before the program has reached the line with the declaration:

    try{
      console.log(b)
    }catch(e){
      console.error(e) //ReferenceError
    }
    
    let b //b initalized here (b===undefined)
    
    console.log(b) //undefined
    b=3   //Reassign b with 3
    console.log(b) //3
    

    The initialization happens even if the let lacks =value part, in this case, with the value undefined, so it won't throw error anymore.

    That's why you can't omit the =value part from a const declaration: it would be initalized with undefined and couldn't be reassigned later.

    Also note that this kind of error is different from the error when trying to access an undefined variable: the former is thrown even if the variable is defined (in another scope):

    let b=1
    console.log(b) //1
    {
      //Different scope
      try{
        console.log(b)
      }catch(e){
        console.error(e) //ReferenceError: the inner b shadows the outer, but not yet initialized
      }
      let b=2
      console.log(b) //2
    }