Blog hero
Nov 29, 2019

What is the 'Temporal Dead Zone' in JavaScript?

This concept is probably not something that you come across too often and sounds a little bit weird. But it can be useful to know some details to avoid possible bugs or problems in your code.


So, let's look at the example below. It's easy to see that it will print foo to console.
var foo = 'foo';
console.log(foo); // foo

What if we change the order of the lines as below:
console.log(foo);
var foo = 'foo';

Now you will see that it prints undefined. This is because the var declaration is hoisted but the value of variable is undefined when console.log line is executed.


Now let's add a bit of ES6 to our simple example.
console.log(foo);
let foo = 'foo';

If you run this code on your console, you will get a ReferenceError. This is one of the main differences between var and let/const. When let/const variables are accessed before their declaration, they throw a ReferenceError instead of having undefined value.

You may think that let/const variables are not hoisted and we're getting ReferenceError because of this, but this is not correct.


Let's explain that in a little bit more complex example.
var foo = 'first';
function example() {
  console.log(foo);
  var foo = 'second';
}
example();

What do you think the code above will print to console?

The answer is undefined. This is a simple example that explains how hoisting works in JavaScript. foo variable is hoisted inside of the function scope but it's not initialized where the console.log line is executed, so it prints undefined. This is the expected result.


So what if we change it as below?
let foo = 'first';
function example() {
  console.log(foo);
  let foo = 'second';
}
example();

This code above will throw a ReferenceError similar to the let example before. This is because let/const variables are actually hoisted, but they throw ReferenceError if they're accessed before being initialized. The variable is in a "temporal dead zone" from the start of the block until the initialization is processed.

If you want to dig deeper you can see MDN documentation of let here, and ES specification here.

There is a misconception that says let/const are not hoisted in JavaScript, we cannot say that is correct. According to ES6 specification: The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated.

Note: You can see another great explanation of hoisting of let/const here.