Temporal Dead Zone

Temporal Dead Zone

ES6 introduced two new ways to declare variables const and let, which mostly replaces the old practice of using var. Let's briefly look into the difference between these three ways.

var vs const vs let

varconstlet
DeclarationsGlobally scoped or function scoped.Block scoped.Block scoped.
Updation and Re-declaration of variableUpdated and re-declared within its scope.Neither be updated nor re-declared.Updated but not re-declared.
InitializationHoisted to the top of their scope and are initialized with undefined.Hoisted to the top of their scope but are not initialized.Hoisted to the top of their scope but are not initialized.
DeclarationCan be declared without initialization.Must be initialized during declaration.Can be declared without initialization.

Temporal Dead Zone

A variable declared by let or const has a temporal dead zone: When entering its scope, it can’t be accessed until execution reaches the declaration.

Variables exist in the TDZ from the place they get bound (when the variable gets bound to the scope it's inside) until it is declared (when a name is reserved in memory for that variable).

If a variable is accessed before it is declared it gives a ReferenceError. var does not do that it just default initialize to undefined.

Example

let tmp = true;
if (true) { // Enter new scope, TDZ starts
    // Uninitialized binding for `tmp` is created
    console.log(tmp);  // ReferenceError
    let tmp; // TDZ ends, `tmp` is initialized with `undefined`
    console.log(tmp); // undefined
    tmp = 1;
    console.log(tmp); // 1
}
console.log(tmp); // true

Moreover, the dead zone is temporal and not spatial.

Example

if (true) { // enter new scope, TDZ starts
    const func = function () {
        console.log(tmp); // No Error
    };

    // Here we are within the TDZ and
    // accessing `tmp` would cause a `ReferenceError`

    let tmp= 2; // TDZ ends
    func(); // called outside TDZ
}

Here, we can see even though tmp variable is used in the function but it does not give an error cause the function is called outside the TDZ.

Why Temporal Dead Zone?

You might be wondering if TDZ was not needed before ES6 why include it now? Mainly cause of hoisting.

What is hoisting?

It refers to the process where the interpreter appears to move the declaration of functions, variables, or classes to the top of the scope, prior to execution of the code. Variables are hoisted so they can be referenced before they are declared.

However, JS only hoists declarations, not initialization. Variables are hoisted and assigned a default value. Due to which a variable declared with var has a default value as undefined but a variable declared as let or const does not have a default value resulting in an exception when read before initialization.

console.log(tmp); // Throws ReferenceError exceptions as tmp variable value is not initialized
let tmp = 1; // Initialization

Capture.PNG Thus, due to this reason we have TDZ in const and let but not var.

How to avoid TDZ Errors?

We just need to make sure we define the const and let variables at the top of the scope.