[JavaScript] Deep Dive into Temporal Dead Zone (TDZ)

[JavaScript] Deep Dive into Temporal Dead Zone (TDZ)

Introduction

Can you predict the output of these snippets of JavaScript code? Would the error occur?

const hyundai = new Car();

class Car {
  constructor(color) {
    this.color = color;
  }
}
// Error or not?
myFunc();

function myFunc() {
  console.log("a");
}
// Error or not?
console.log(myFunc(3, 5));
let myFunc = (a, b) => a + b;
// Error or not?
console.log(str);
let str = "JS"
// Error or not?

The answer is that the last two will have the ReferenceError. Even though your answer was correct, if you guessed it or if you do not know why the ReferenceError occurs, this article will be helpful to you.

In this article, I will be talking about Hoisting and Temporal Dead Zone (TDZ) as well as the differences between var, let and const.


var, let, const, function Declaration

Whenever you declare a variable, there will be three stages involved.

  1. Declaration - Registering a variable in the scope.

  2. Initialization - Allocating memory and creating a binding for the variable. In this phase, the variable is assigned a value undefined.

  3. Assignment - Assigning a value by using the assignment operator(=).


JavaScript Variables Lifecycle: Why let Is Not Hoisted

For the var variables, both the declaration and initialization phases occur at the same time, which means:

var a; // declaration and initialization
console.log(a); // no error. prints undefined

Although I haven't assigned any values, it already has an undefined value.

You can do something like this:

console.log(a); // prints undefined. no error.
var a;

When declaring a function, the stages are like this. All the three phases happen at the same time.

So there is no error when you do this:

a(); // no error.
function a() {
    console.log("Jay's Dev Blog");
}

JavaScript Variables Lifecycle: Why let Is Not Hoisted

Please have a look at the diagram above. Notice that the declaration and initialization phases do not happen at the same time. More importantly, there is something called Temporal Dead Zone between the two stages. It indicates that "Accessing variable throws ReferenceError".

*Note. The life cycle diagram is the same for const, too.

Let's have a look at this code:

console.log(letVar); // Temporal Dead Zone
console.log(constVar); // Temporal Dead Zone
let letVar;
const constVar;

Unlike var, this results in ReferenceError because the area above letVar and constVar are said to be a temporal dead zone. So, what is the temporal dead zone and why is it said to be the TDZ?


Temporal Dead Zone

Unlike var, the declaration and initialization do not occur at the same time, which means there are no values (even undefined) assigned in the memory spaces for both letVar and constVar variables. Therefore, the JavaScript engine cannot refer to those two variables.

Don't Use JavaScript Variables Without Knowing Temporal Dead Zone

Declarations that are affected by the TDZ

  1. let - explained above

  2. const - explained above

  3. super()

  4. class

  5. default function parameter


class

let car = new Car(); // TDZ

class Car {
    constructor(color) {
        this.color = color;
    }
}

You can create a new instance after the declaration of the class. Otherwise, the JavaScript engine cannot refer to the class.


super()

class MiniVan extends Car {
    constructor(color, power) {
        this.power; // TDZ
        super();
    }
}

The super() must be called before this keyword. Before calling super() this binds to TDZ


Default Function Parameter

let a = 5
function myFunc(a = a) {
    return a * a;
}
console.log(myFunc()); // ReferenceError

When you want to use the default function parameter, avoid using the same variable name as the default parameter.

Better code:

let num = 5;
function myFunction(a = num) {
    return a * a;
}
console.log(myFunc()); // 25

Declarations that are NOT affected by the TDZ

  1. var - explained above

  2. function - explained above

These two are explained above. They are not affected because the declaration and initialization phases occur at the same time, so undefined is assigned in the memory spaces. This means that the JavaScript engine can refer to the variable or function.

Did you find this article valuable?

Support Jay's Dev Blog by becoming a sponsor. Any amount is appreciated!