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

> Understand JavaScript's temporal dead zone TDZ with let and const. Learn why accessing variables before declaration causes ReferenceErrors and how to avoid them.

- Repository: [Lydia Hallie/javascript-questions](https://github.com/lydiahallie/javascript-questions)
- Tags: deep-dive
- Published: 2026-03-04

---

**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](https://github.com/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](https://github.com/lydiahallie/javascript-questions) repository provides a clear comparison in its main documentation. As noted in [[`README.md`](https://github.com/lydiahallie/javascript-questions/blob/main/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:

```javascript
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:

```javascript
{
  // 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:

```javascript
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`:

```javascript
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](https://github.com/lydiahallie/javascript-questions) repository appears in the main documentation file. The primary source is [[`README.md`](https://github.com/lydiahallie/javascript-questions/blob/main/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/main/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](https://github.com/lydiahallie/javascript-questions) repository documents this behavior in [[`README.md`](https://github.com/lydiahallie/javascript-questions/blob/main/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.