What Is the Temporal Dead Zone with let and const in JavaScript?

The temporal dead zone (TDZ) is the period between entering a scope and executing a let or const declaration, during which accessing the variable throws a ReferenceError because the binding exists but remains uninitialized.

The concept of the temporal dead zone represents one of the most critical behavioral differences between modern JavaScript variable declarations and legacy var usage. According to the lydiahallie/javascript-questions repository—a widely-used resource for JavaScript interview preparation—understanding this mechanism is essential for avoiding common runtime errors. The temporal dead zone specifically affects variables declared with let and const, creating a strict initialization requirement that var does not enforce.

Understanding the Temporal Dead Zone Mechanism

Hoisting Without Initialization

While both var and let/const declarations are hoisted to the top of their respective scopes, they behave differently during the creation phase. Variables declared with var are hoisted and immediately initialized with the value undefined. In contrast, let and const bindings are hoisted to the scope but remain uninitialized—they exist in a binding state that has no value.

The Dead Zone Period

The temporal dead zone begins at the start of the enclosing scope (block, function, or module) and ends when the JavaScript engine executes the line containing the variable declaration. During this interval, any attempt to access the variable—whether reading or writing—results in a ReferenceError. This behavior intentionally prevents the use of variables before their declaration line, catching potential bugs that var would silently ignore by returning undefined.

How let and const Differ from var

The lydiahallie/javascript-questions repository provides a clear comparison in its main documentation. As noted in [README.md](https://github.com/lydiahallie/javascript-questions/blob/master/README.md) at line 79:

"Variables with the let keyword (and const) are hoisted, but unlike var, don't get initialized. They are not accessible before the line we declare (initialize) them. This is called the temporal dead zone. When we try to access the variables before they are declared, JavaScript throws a ReferenceError."

Key Differences:

  • var: Hoisted with initialization to undefined; accessible before declaration (returns undefined); function-scoped; allows re-declaration.
  • let: Hoisted without initialization; throws ReferenceError if accessed before declaration; block-scoped; no re-declaration allowed.
  • const: Same hoisting behavior as let; additionally requires initialization at declaration; block-scoped; no re-declaration or reassignment allowed.

Practical Code Examples of the TDZ

Basic TDZ Error

Accessing a let variable before its declaration line triggers the temporal dead zone:

console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 10;

TDZ Within Block Scopes

The dead zone respects block boundaries. Inside a new block, the TDZ starts fresh:

{
  // console.log(b); // Uncommenting throws ReferenceError: Cannot access 'b' before initialization
  const b = 'inside block';
  console.log(b); // 'inside block'
}

TDZ with Function Default Parameters

Default parameter expressions exist in their own scope, creating TDZ interactions between parameters:

function greet(name = defaultName) {
  // ReferenceError: defaultName is not defined yet (TDZ within parameter scope)
  const defaultName = 'World';
  return `Hello, ${name}!`;
}
greet(); // throws ReferenceError

Comparing var and let Behavior

This example demonstrates how var avoids the TDZ by initializing with undefined:

console.log(x); // undefined (hoisted and initialized)
var x = 5;

console.log(y); // ReferenceError: Cannot access 'y' before initialization (TDZ)
let y = 5;

Source Code Reference

The explanation of the temporal dead zone in the lydiahallie/javascript-questions repository appears in the main documentation file. The primary source is [README.md](https://github.com/lydiahallie/javascript-questions/blob/master/README.md), specifically around line 79, where the repository author defines the TDZ and contrasts it with var hoisting behavior.

Additionally, the repository maintains language-specific translations (such as [README_pt_BR.md](https://github.com/lydiahallie/javascript-questions/blob/master/pt-BR/README_pt_BR.md)) that preserve this technical explanation across different locales, confirming the consistency of the TDZ definition throughout the project.

Summary

  • The temporal dead zone (TDZ) is the period between entering a scope and executing a let or const declaration, during which the variable binding exists but remains uninitialized.
  • Accessing a variable within the TDZ throws a ReferenceError, unlike var which returns undefined when accessed before declaration.
  • Both let and const are hoisted to the top of their block scope, but they do not receive an automatic initialization value, creating the dead zone.
  • The lydiahallie/javascript-questions repository documents this behavior in [README.md](https://github.com/lydiahallie/javascript-questions/blob/master/README.md) as a critical distinction between modern and legacy variable declarations.

Frequently Asked Questions

What error does the temporal dead zone throw?

The temporal dead zone throws a ReferenceError with the message "Cannot access [variable] before initialization" when you attempt to access a let or const variable before its declaration line executes. This differs from the "is not defined" error that occurs when a variable does not exist at all.

Does var have a temporal dead zone?

No, variables declared with var do not have a temporal dead zone. While var declarations are hoisted to the top of their function scope, they are immediately initialized with the value undefined. This means accessing a var variable before its declaration returns undefined rather than throwing an error.

Can you check if a variable is in the temporal dead zone?

There is no direct method to check if a variable is currently in the temporal dead zone. The TDZ is an internal JavaScript engine mechanism, not an observable state you can query programmatically. Attempting to access the variable is the only way to detect the TDZ, and that action immediately throws a ReferenceError.

Does the temporal dead zone affect function declarations?

Function declarations are hoisted differently than variables and do not experience the temporal dead zone. A function declaration is hoisted to the top of its scope with its full definition, meaning you can call the function before its declaration line in the code. However, if a function is assigned to a let or const variable (function expression), the TDZ applies to the variable binding, not the function itself.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →