What Is the Temporal Dead Zone

What is the temporal dead zone?

let and const have two broad differences from var:

  1. They are block scoped.
  2. Accessing a var before it is declared has the result undefined; accessing a let or const before it is declared throws ReferenceError:

console.log(aVar); // undefined
console.log(aLet); // Causes ReferenceError: Cannot access 'aLet' before initialization

var aVar = 1;
let aLet = 2;

If let is not hoisted or they goes in temporal dead zone, then why this snippet is throwing error, when it could have just used the global reference

The answer to your question is in your title: the variable is in a "temporal dead zone", which is just a name for the behaviour you're seeing.

Take this explanation on MDN:

Unlike variables declared with var, which will start with the value undefined, let variables are not initialized until their definition is evaluated. Accessing the variable before the initialization results in a ReferenceError. The variable is in a "temporal dead zone" from the start of the block until the initialization is processed.

The start of the block is the opening { and your console.log(a) comes before let statement, so it is in this "dead zone".

Why does it work that way? Because it helps programmers detect bugs in their code caused by confusion between variables with the same name in different scopes.

Why does the temporal dead zone exists?

It makes sense for a variable to exist from the moment it is defined. Due to the way variables from an outside scope are accessible within nested scopes, the following code is very confusing:

var foo = 'out';

function bar () {
foo = 'in';
console.log(foo);
var foo;
}

bar();

What does the function bar() do? It creates a new variable called foo and assigns 'in' to it before showing it in the console. The variable from the outside scope is still equal to 'out' after that. So it's a much smarter thing to define variables before you use them. I believe the fact that you can use a variable before it is declared is only a question of implementation simplicity and efficiency, but I'm boldly guessing here.

However, in JS, variables created with the var keyword are accessible from within their function, not their block. This allows more permissive syntax like the following:

function setGameMode (mode) {
if (mode === 'peaceful') {
var count = 0;
for (var i = 0; i < mobs.length; ++i) {
if (mobs[i] instanceOf EvilMob) {
mobs[i].despawn();
++count;
}
}
console.log('Removed ' + count+ ' evil mobs out of ' + i);
mobSpawner.evil = false;

} else if (mode ==='chaotic') {
var count = 0;
for (var i = 0; i < mobs.length; ++i) {
if (mobs[i] instanceOf NiceMob) {
mobs[i].despawn();
++count;
}
}
console.log('Removed ' + count + ' nice mobs out of ' + i);
mobSpawner.nice = false;
}
}

The i variable still exists after the for loop thanks to function-scoped variables. This is also why the var keyword allows you to define a variable twice. It just wouldn't be practical if you were forced to write var only once. With a let variable, this "loose" feature becomes useless as these variables should be freed as soon as they are no longer needed.

When you call a function in most programming languages, the execution environment creates a space in memory for the variables you'll need. Here, there's no way to tell if the variable i will be needed without actually running the code because it's inside an if block. Still, since JS has function-scoped variables, it has to create the variable from the start of the function. There's no need for this in the case of let variables.

As for the reason behind typeof someundefinedvar returning 'undefined', well it's because you need a way to check for variables that might have been declared in outside scopes. However, you don't need that feature for variables that are block-scoped. let variables are meant to be used immediately and thrown away.

ECMAScript 2015 Temporal Dead Zone

That's the way it goes:

Temporal dead zone and errors with let

In ECMAScript 2015, let will hoist the variable to the top of the block. However, referencing the variable in the block before the variable declaration results in a ReferenceError. The variable is in a "temporal dead zone" from the start of the block until the declaration is processed.



Related Topics



Leave a reply



Submit