What is Temporal Dead Zone?

What is Temporal Dead Zone?

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 get undefined .

References