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:
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 toundefined
when they get hoisted.And that's the sole reason we have the TDZ. Which is why it happens with
let and const
but notvar.
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...