Skip to main content

JavaScript Scope & Hoisting

JavaScript Temporal Dead Zone

Written by Published

The JavaScript temporal dead zone is the gap between entering a scope and reaching a let or const declaration.

Inside that gap the variable exists but cannot be touched.

Reading it throws a ReferenceError, which is far more helpful than a silent undefined.

Example

Example

javascript

let ready = true;

console.log(ready);

This works because the declaration comes first.

Moving the console.log above the declaration would throw an error.

What is the Temporal Dead Zone?

When JavaScript enters a scope, it registers every let and const in it.

Those variables are then held in an unusable state until their declaration line runs.

That unusable period is the temporal dead zone, usually shortened to TDZ.

Syntax

Syntax

javascript

{
  // TDZ for value starts here
  let value = 10;
  // TDZ ends; value can now be used
}

The zone is about time, not position: it ends when the line actually runs.

Why It Exists

var quietly gives undefined, which hides mistakes.

The TDZ turns the same mistake into a clear error message.

Example

Example

javascript

var oldStyle;

console.log(oldStyle);

var prints undefined, so a typo can go unnoticed for a long time.

const Has the Same Rule

const behaves exactly like let here.

Example

Example

javascript

const rate = 1.2;

console.log(rate * 100);

Reading rate before this line would throw the same error.

The TDZ is Per Block

Each block has its own zone, so an inner declaration shadows an outer one from the start.

Example

Example

javascript

let value = "outer";

{
  let value = "inner";
  console.log(value);
}

console.log(value);

Inside the block, the inner variable is in charge from the opening brace.

Reading value before the inner declaration would be an error, not "outer".

typeof is Not Safe Either

typeof on an undeclared variable is safe and returns "undefined".

typeof on a variable in its TDZ still throws.

Example

Example

javascript

console.log(typeof neverDeclared);

let declared = 1;
console.log(typeof declared);

The first line is safe; a typeof above declared would not be.

Avoiding the TDZ

Declare each variable before the first line that uses it, and the zone never matters.

Example

Example

javascript

function greet(name) {
  const greeting = "Hello";
  return greeting + " " + name;
}

console.log(greet("Ada"));

Declaring at the top of the block is the simplest habit that avoids the problem.

Complete Example

Complete Example

html

<!DOCTYPE html>
<html>
<head>
  <title>JavaScript Temporal Dead Zone</title>
</head>
<body>

  <h1>JavaScript Temporal Dead Zone</h1>

  <p id="result"></p>

  <script>
    let output = "";

    output += "typeof an undeclared name: " + typeof neverDeclared + "<br>";

    let declared = "ready";

    output += "after declaration: " + declared;

    document.getElementById("result").innerHTML = output;
  </script>

</body>
</html>

Try It Yourself

Run the above example in the Try It Editor.

Try reading it too early:

Add console.log(declared); as the first line and watch the console error.

Important Points

  • The TDZ is the gap between entering a scope and reaching a let or const line.
  • Reading a variable in its TDZ throws a ReferenceError.
  • var has no TDZ; it quietly gives undefined.
  • typeof does not protect you inside the TDZ.
  • Declaring before use means the TDZ never affects you.

Conclusion

The JavaScript temporal dead zone turns a silent bug into a clear error.

It is one of the main reasons let and const are safer than var.

Understanding the TDZ explains error messages that otherwise look mysterious.