A temporal dead zone (TDZ) is the area of a block where a variable is inaccessible until the moment the computer completely initializes it with a value. But wait we are not directly going to jump into the depth of the temporal dead zone. So It all starts with the hoisting. We are not going to cover in-depth hoisting as there will be a dedicated blog for hoisting but there will be a basic intro to hoisting.
What is Hoisting?
If I have to explain the meaning of Hoisting in general it means "to lift or pull something up". Now In Javascript Hoisting is a consequence or result of lexical scoping, due to which we are able to access some functions and variables before declaring them which gives us the notion that they are lifted up or moved up in the file.
So now where is the Temporal Dead Zone coming from so the answer is it's a consequence of or result of hoisting in Block Scope.
Understanding Temporal Deadzone In Depth
The temporal Dead Zone TDZ is part of the code where the variables are not accessible, they are in scope according to the declaration but we can't access them.
The temporal Dead Zone starts when the code execution enters the block which contains the let
or const
declaration and continues until the declaration has been executed.
So what happens with the temporal dead zone is that when we try to access any let or const variable before its complete initialization, Javascript throws a reference error.
let name = 'Munna Bhaiya';
function printName() {
console.log(name);
let name = 'Guddu Bhaiya';
}
printName(); // Error ReferenceError: Cannot access 'name' before initialization
So let's take our above example to understand properly what temporal dead zone is doing so,
In the first line variable name is declared using let
, we know that let is a block-scoped. since the name is declared outside so it is a global variable. Now inside the function printName() we are printing the name variable than in the next line we are declaring the name variable again then we call the function printName(). So what's happening here is that inside printName() function there is a new scope opened now when we try to access the name variable it will look for name declaration but it won't find any variable declared within the function printName() hence it will throw reference error that it cannot access name variable.
But where exactly does the TDZ begin and end? Let’s find out below.
(Disclaimer - Example taken from Free Code Camp Article)
A block’s temporal dead zone starts at the beginning of the block’s local scope. It ends when the computer fully initializes your variable with a value.
Here’s an example:
{
// bestFood’s TDZ starts here (at the beginning of this block’s local scope)
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
console.log(bestFood); // returns ReferenceError because bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
let bestFood = "Vegetable Fried Rice"; // bestFood’s TDZ ends here
// bestFood’s TDZ does not exist here
// bestFood’s TDZ does not exist here
// bestFood’s TDZ does not exist here
}
In the snippet above, the block’s TDZ starts from the opening curly bracket ({
) and ends once the computer initializes bestFood
with the string value "Vegetable Fried Rice"
.
When you run the snippet, you will see that the console.log()
the statement will return a ReferenceError
.
JavaScript will return a ReferenceError
because we used the console.log()
code to access bestFood
before its complete initialization. In other words, we invoked bestFood
within the temporal dead zone.
However, here is how you can access bestFood
successfully after its complete initialization:
{
// TDZ starts here (at the beginning of this block’s local scope)
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
let bestFood = "Vegetable Fried Rice"; // bestFood’s TDZ ends here
console.log(bestFood); // returns "Vegetable Fried Rice" because bestFood’s TDZ does not exist here
// bestFood’s TDZ does not exist here
// bestFood’s TDZ does not exist here
}
Now, consider this example:
{
// TDZ starts here (at the beginning of this block’s local scope)
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
let bestFood; // bestFood’s TDZ ends here
console.log(bestFood); // returns undefined because bestFood’s TDZ does not exist here
bestFood = "Vegetable Fried Rice"; // bestFood’s TDZ does not exist here
console.log(bestFood); // returns "Vegetable Fried Rice" because bestFood’s TDZ does not exist here
}
You can see that the first console.log
code in the snippet above returned undefined
.
JavaScript returned undefined
because we did not assign bestFood
a value before using (invoking) it. As such, JavaScript defaulted its value to undefined
.
Keep in mind that you must specify a value for a const
variable while declaring it. Apart from this exception, all other temporal dead zone principles of let
variables apply also to const
. However, var
works differently.
So TDZ happens only with let
and const
?
Well this can be a good question though the answer is straightforward Temporal Dead Zone happens with var
. But the TDZ behaves differently with var
compared to let
and cosnt
.
Let's understand this with an example :
console.log(name);
var name = "Akash";
console.log(name);
// Output - undefined
// Akash
You must be surprised with the results as it does not throw any error, Well that's the difference. Here when we try to access the name variable before initializing it, we get undefined
and then after that when name = "Akash" initialized then we get output as Akash.
when the computer hoists a var
variable, it automatically initializes the variable with the value undefined
whereas JavaScript does not initialize a let
(or const
) variable with any value whenever it hoists the variable. Instead, the variable remains dead and inaccessible.
Therefore, a let
(or const
) variable’s TDZ ends when JavaScript fully initializes it with the value specified during its declaration.
However, a var
variable’s TDZ ends immediately after its hoisting—not when the variable gets fully initialized with the value specified during its declaration.
Conclusion
In this article we understood about Temporal Dead Zone and How does Temporal Dead Zone behave with var, let & const
. The Temporal Dead Zone is related to hoisting and Hoisting is a consequence of Lexical Scoping.
Tips I can share with you if you want to escape the Temporal Dead Zone is
1 - Always declare and initialize the variables first before accessing it .
2 - Use
let
&const
to declare variables or else if TDZ happens with variable declared with var you will getundefined
.