Complete Guide on Temporal Dead Zone of 
                                                    JavaScript

Complete Guide on Temporal Dead Zone of JavaScript

By reading you can completely understand temporal dead zone of javascript

Temporal Dead Zone is an important term in JavaScript. But understanding how it works can easily confuse you if you don't approach it correctly.

But don't fret! This article is here to help you grasp the term well.

What Exactly Is a Temporal Dead Zone in JavaScript?

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.

  • A block is a pair of braces ({...}) used to group multiple statements.

  • Initialization occurs when you assign an initial value to a variable.

Suppose you attempt to access a variable before its complete initialization. In such a case, JavaScript will throw a ReferenceError.

Before ES6 there was no other way to declare variables other than var. But ES6 brought uslet and const.

let and const declarations are both block-scoped, which means they are only accessible within the { } surrounding them. var, on the other hand, doesn't have this restriction.

Here's an example:

let myAge = 1;
let isDay = true;

if (isDay) {
    let myAge = 2; 
}

console.log(myAge); // Hmmmm. This prints 1

Two unique variables, with different values.

The above has occurred because the re-declaration of myAge to 2 is only available inside the if block. Beyond that, the first myAge is used. Can you see that they are two different variables?

In contrast, the var declaration has no block scope:

var myAge = 1;
var isDay = true;

if (isDay) {
    var myAge = 2; 
}
console.log(myAge); // Ah! This prints 2

One variable with its value re-declared. The final salient difference between let/const and var is that if you access var before it's declared, it is undefined. But if you do the same for let and const, they throw a ReferenceError.

console.log(varNumber); // undefined
console.log(letNumber); // Doesn't log, as it throws a ReferenceError letNumber is not defined

var varNumber = 1;
let letNumber = 1;
They throw the error all because of the Temporal Dead Zone.

Temporal Dead Zone explained

The let and const variables exist in the TDZ from the start of their enclosing scope until they are declared.

You could also say that the 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).

{
     // This is the temporal dead zone for the age variable!
    // This is the temporal dead zone for the age variable!
    // This is the temporal dead zone for the age variable!
     // This is the temporal dead zone for the age variable!
    let age = 25; // Whew, we got there! No more TDZ
    console.log(age);
}

You can see above that if I accessed the age variable earlier than its declaration, it would throw a ReferenceError. Because of the TDZ.

But var won't do that. var is just default initialized to undefined unlike the other declaration.

Why is the TDZ created ?

let's go back to our first example:

{
    // This is the temporal dead zone for the age variable!
    // This is the temporal dead zone for the age variable!
    // This is the temporal dead zone for the age variable!
    console.log(age);
    // This is the temporal dead zone for the age variable!
    let age = 25; // Whew, we got there! No more TDZ
}

If we add a console.log inside the TDZ you will see this error:

image-5.png

Why does the TDZ exist between the top of the scope and the variable declaration? What's the specific reason for that?

It's because of hoisting.

The only difference is that when const and let are hoisted, their values don't get defaulted to undefined. Just to prove let and const also hoist, here's an example:

{
    // variable will be hoisted to the top of their scope!
    console.log(name); // Throws an error, cannot access 'name' before initialization

    let name = "chhakuli";
}

The above snippet is proof that let is clearly hoisted above where it was declared, as the engine alerts us to the fact. It knows name exists (it's declared), but we can't access it before it is initialized.

If it helps you to remember, think of it like this.

When variables get hoisted, var gets undefined initialized to its value by default in the process of hoisting. let and const also get hoisted, but don't get set to undefined when they get hoisted.

And that's the sole reason we have the TDZ. Which is why it happens with let and const but not var.

Why do we have the TDZ?

Dr Alex Rauschmayer has an excellent post on why the TDZ exists, and the main reason is this:

It helps us catch errors.

To try and access a variable before it is declared is the wrong way round, and shouldn't be possible.

It also gives more expected and rational semantics for const (because const is hoisted, what happens if a programmer tries to use it before it is declared at runtime? What variable should it hold at the point when it gets hoisted?), and was the best approach decided by the ECMAScript spec team.

How to avoid the issues the TDZ causes

Relatively simply, always make sure you define your lets and consts at the top of your scope.

Thanks for reading...

Did you find this article valuable?

Support Chhakuli Zingare by becoming a sponsor. Any amount is appreciated!