DEV Community

Discussion on: Understanding Hoisting

Collapse
 
miketalbot profile image
Mike Talbot ⭐ • Edited

This is indeed a very clear description - I would say though that definitions of a let or const are hoisted, but are not allowed to be accessed for read or write before first definition. This is a subtle difference ofc.

function someFunction() {
     function innerFunctionThatMakesAClosure() {
         return value;
     }
    let value = 1000;
    return innerFunctionThatMakesAClosure;
}
console.log(someFunction()()); // -> 1000
Enter fullscreen mode Exit fullscreen mode

The definition was hoisted to create the closure, as the inner function appears lexically before the declaration of the variable.

Collapse
 
skaytech profile image
skaytech

Thanks for the clarification Mike!! Glad you liked the explanation.

Collapse
 
miketalbot profile image
Mike Talbot ⭐

It's a really nice article :)

Collapse
 
z2lai profile image
z2lai • Edited

Very good point Mike, but I think some terminology needs to be clarified. Variable declarations (variable name bindings to memory) with let and const are hoisted, not their definitions (i.e. function definitions). But they cannot be accessed for read/write before their first assignment (initialization).

The provided example is pretty neat, here's a more basic example without closures:

console.log(randomVar); // console will return Uncaught ReferenceError: randomVar is not defined
console.log(hoistedVar); // console will return Uncaught ReferenceError: Cannot access 'hoistedVar' before initialization
function log() {
  console.log(hoistedVar); // console will not return any error as this line isn't actually executed yet, so hoistedVar is not being accessed
}
log(); // console will return Uncaught ReferenceError: Cannot access 'hoistedVar' before initialization
let hoistedVar = "Hi"; // hoistedVar is initialized here
log(); // console will log "Hi"

Note that the ReferenceError from trying to access the hoisted "let" variable declaration is different than the ReferenceError from trying to access a variable that has not been declared at all.

So to reiterate the original point made, all variable declarations are hoisted, but let and const variable declarations will give a ReferenceError if the variable is accessed before being initialized.

Collapse
 
skaytech profile image
skaytech

Yes. Agreed. This was also mentioned previously by Mike in the comment below. I'll update the article with this comment.