In JavaScript, the hoisting
of variables declared with var
is well known among JavaScript developers.
Javascript’s ES2015 version introduced two new keywords to declare variables and constants: let
and const
.
Unlike var
, which can be accessed before it is declared, variables declared with let
and constants declared using const
cannot be accessed before their declaration.
console.log(foo); // undefined
var foo = 123;
console.log(foo); // Error
let foo = 123;
This might lead you to think that hoisting
doesn’t apply to let
and const
; that is an incorrect assumption.
This might come as a surprise, but similar to var
, variables declared with let
and constants declared using const
are also hoisted; it is just that how they are hoisted is different from how var
variables are hoisted.
Let’s look at an example of code that proves that variables declared using let
are also hoisted.
let age = 50;function printAge() {console.log(age);let age = 30;}printAge(); // Error
Running the code snippet above throws an error even though the variable age
is declared in the global scope. This is because the console.log
statement inside the printAge
function doesn’t have access to that outer age
variable, since another age
variable is declared within the printAge
function.
If the let
variables weren’t hoisted, JavaScript would have logged the global age
variable. But, if we look at the output of the code snippet, we see that this is not the case.
This proves that the variables declared with let
are also hoisted. The same applies to the const
keyword.
So, if the let
and const
are also hoisted, why is it that they cannot be accessed before their declaration? The answer to this lies within the concept of the Temporal Dead Zone (TDZ).
Variables declared using let
and the constants declared using const
are hoisted but are in a TDZ. This prevents them from being accessed before their declaration has actually been executed during the step-by-step execution of the code.
Temporal Dead Zone is the period of time during which the let
and const
declarations cannot be accessed.
Temporal Dead Zone starts when the code execution enters the block which contains the let
or const
declaration and continues until the declaration has executed.
In our code example above, Temporal Dead Zone starts after the opening parenthesis of the printAge
function and continues until after the declaration of the age
variable.
Consider the following code example that illustrates an interesting point about the Temporal Dead Zone.
function print() {function log() {console.log(age);}const age = 20;log();}print(); // 20
How are we able to access age
before its declaration?
Actually, age
is accessed after the declaration of age
variable because the console.log
is inside another function that is called after the declaration of the age
variable. By the time the age
variable is accessed inside the log
function, the age
variable’s declaration has already been executed.
This means that it’s not about where, but about when the let
variable or const
constant is accessed. Temporal Dead Zone relates to time, not the space above the declaration of let
or const
.