Understanding Temporal Dead Zone in Javascript

Listen to this article

Variables declared with var are hoisted, i.e. variable declared with var can be used before it is declared.

age = 20;
var age;

console.log(age);       // 20

In the above code example, we were able to use the variable age before it was declared. This works because of the concept known as hoisting.

This happens because, before starting the step-by-step execution of the code, javascript engine scans through the code, looking for var declarations and hoisting (lifting) them to the top of the scope.

It's important to note that only declarations are hoisted, not their initializers. When var declarations are hoisted, javascript engine assigns the value undefined to that variable.

console.log(age);       // undefined
var age = 20;

In the above code example, variable age was hoisted at the top of the scope but its value is undefined. Variable age will only be assigned the value 20 when the second line of code is executed during the step-by-step execution of the code.

let and const Declarations are also Hoisted

Unlike variables declared with var, variables declared with let or constants declared with const can't be used before they are declared.

console.log(age);  // error: Cannot access uninitialized variable
let age = 20;

In the above code example, we cannot access age variable before it is declared. Instead, we get an error telling us that we cannot access the variable age before it is initialized.

Apparently, the let and const declarations are not hoisted like var declarations. But that is a misconception. let and const declarations are hoisted, too. They are just hoisted differently.

Consider the following code example:

let age;

function foo() {
  age = 20;        // error: Cannot access uninitialized variable
  let age = 30;
}

foo();

If the let declarations weren't hoisted, first line of code inside the foo function should have assigned the value to the variable age that is defined outside the function foo. But that is not the case. Instead, we get an error.

This behaviour avoids confusing code. Imagine, in the above code example, the identifier age inside the foo function referring to two different variables defined in two different scopes. Hoisting of let and const declarations prevents such confusing code.

But if let and const declarations are hoisted, then why can we not access the variables declared with let and constants declared with const, before they are declared?

Answer to the above question is Temporal Dead Zone (TDZ).

Temporal Dead Zone is the period of time during which the let and const declarations cannot be used to refer to anything at all.

As with var declarations, javascript engines processes the let and const declarations before starting the step-by-step execution of the code. Difference is that, instead of assigning the value undefined, javascript engine marks the identifier declared using let or const as "not yet initialized".

Temporal Dead Zone (TDZ) starts when the code execution enters the block which contains the let or const declaration and continues until the declaration is run.

Comments in the following code example show the start and end of Temporal Dead Zone:

let age;

function foo() {
  // temporal dead zone start
  age = 20;       
  let age = 30;
  // temporal dead zone end
}

foo();

Temporal Dead Zone starts as soon as the code execution enters the foo function body and continues until the declaration of variable age is executed.

Temporal Dead Zone is Temporal, not Spatial

One important thing to understand about TDZ is that it is temporal (related to time) and not spatial (related to space or location).

Following code example will make it much more clear:

function foo() {
  function bar() {
    console.log(age);       // 20
  }

  let age = 20;
  bar();
}

foo();

As you can see in the above code example, variable age is used in a function bar that is declared before the declaration of the variable age but we didn't get any error because of Temporal Dead Done. Why is that?

It's because the Temporal Dead Zone relates to the time until the declaration of the variable age is run and not to the space/location above the declaration where the identifier can't be used.

The above code example works because by the time bar function is called, declaration of variable age has already been executed. That's why we didn't get any error and the function bar logged the value of variable age.

If the Temporal Dead Zone was spatial, then the above code example would have given an error because of the usage of variable age in the code that is above the declaration of that variable.

Summary

  • let and const declarations are hoisted too, its just that they are hoisted differently than var declarations
  • Temporal Dead Zone (TDZ) relates to the period of time during which the identifier can't be used

No Comments Yet