I used to think that hoisting only happened to variables declared with
var. But recently, I learned that it also happens to variables declared with
I'll explain what I mean in this article.
I also have a video version of this article you can check out if you're interested.
How Hoisting Works with
Here's how hoisting works on variables declared with
console.log(number) // undefined var number = 10 console.log(number) // 10
number variable is hoisted to the top of the global scope. This makes it possible to access the variable before the line it was declared, without errors.
But what you'll notice here is that only the variable declaration (
var number) is hoisted – the initialization (
= 10) isn't. So when you try to access
number before it is declared, you get the default initialization that happens with var which is
Then, the declaration and initialization line is executed, so accessing
number after that returns the initialized value, 10.
If you try to do the same thing as above with
const, here's what happens:
console.log(number) let number = 10 // or const number = 10 console.log(number)
You get an error that says: ReferenceError: Cannot access 'number' before initialization.
So you can access a variable declared with var before declaration without errors, but you cannot do the same with
This why I had always thought that hoisting only happens with var, it doesn't happen with let or const.
But as I said, I learned recently that variables declared with
const are also hoisted. Let me explain.
Take a look at this example:
console.log(number2) let number = 10
I log a variable called
number2 to the console, and I declare and initialize a variable called
Running this code produces this error: ReferenceError: number2 is not defined
What do you notice between the previous error and this error? The previous error says ReferenceError: Cannot access 'number' before initialization while this new error says ReferenceError: number2 is not defined.
Here's the difference. The former says "cannot access before initialization" while the latter says "is not defined".
number2 variable is because it is not defined – and indeed we didn't define it. We only defined
But the former doesn't say "is not defined", instead it says, "cannot access before initialization". Here's the code again:
console.log(number) // ReferenceError: Cannot access 'number' before initialization let number = 10 console.log(number)
number variable. How does it know? Because
number is hoisted to the top of the global scope.
But why does an error occur? Well, this clarifies the difference between the hoisting behavior with
Variables declared with
const are hoisted WITHOUT a default initialization. So accessing them before the line they were declared throws ReferenceError: Cannot access 'variable' before initialization.
But variables declared with
var are hoisted WITH a default initialization of undefined. So accessing them before the line they were declared returns
Temporal Dead Zone
There's a name for the period during execution where
const variables are hoisted but not accessible: it's called the Temporal Dead Zone.
Again, the code from above:
console.log(number) let number = 10 console.log(number)
If you were like me, and you thought that hoisting only applies with
var and not
const, I hope this article clears up that false assumption.
As I've explained in this article,
const variables are hoisted, only they are hoisted without a default initialization. This makes them inaccessible (as such variables are in a temporal dead zone).
Variables declared with
var, on the other hand, are hoisted with a default initialization of
I hope you learned something from this article :)