# How JavaScript Hoisting Works: var vs let vs const Explained

> Understand JavaScript hoisting with var let and const. Learn how declarations move to the top and discover the difference in initialization for var let and const.

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

---

**JavaScript hoisting moves all declarations to the top of their scope during the creation phase, but while `var` variables are initialized with `undefined`, `let` and `const` remain uninitialized in the Temporal Dead Zone until their declaration line.**

Understanding JavaScript hoisting is essential for debugging scope-related bugs and writing predictable code. According to the [lydiahallie/javascript-questions](https://github.com/lydiahallie/javascript-questions) repository, the JavaScript engine creates a *creation phase* before executing any code, during which declarations are processed differently depending on whether you use `var`, `let`, or `const`.

## What Is JavaScript Hoisting?

Hoisting is JavaScript’s default behavior of moving declarations to the top of the current scope (script or function) during the compilation phase. This means you can reference variables and functions before they are declared in the source code. However, **only declarations are hoisted**, not initializations. The specific behavior depends on the keyword used to declare the variable.

## How var Hoisting Works in JavaScript

When you declare a variable with `var`, JavaScript hoists the declaration to the top of the function or global scope and **immediately initializes it with `undefined`**.

### Initialization with undefined

As documented in the repository's [`README.md`](https://github.com/lydiahallie/javascript-questions/blob/main/README.md) at line 77, `var` declarations are processed during the creation phase and assigned the value `undefined` until the assignment line is reached. This means accessing the variable before its declaration does not throw an error—it simply returns `undefined`.

```javascript
function varDemo() {
  console.log(name); // → undefined (no error)
  var name = 'Alice';
  console.log(name); // → Alice
}
varDemo();

```

In this example, the first `console.log` succeeds because `name` exists (hoisted) with the value `undefined`. The actual assignment `'Alice'` happens only when execution reaches that line.

## How let and const Hoisting Works

Variables declared with `let` and `const` are also hoisted, but they behave differently than `var`. They are **not initialized** during the creation phase and instead enter the *Temporal Dead Zone* (TDZ).

### The Temporal Dead Zone (TDZ)

According to [`README.md`](https://github.com/lydiahallie/javascript-questions/blob/main/README.md) at lines 79 and 3621 in the [lydiahallie/javascript-questions](https://github.com/lydiahallie/javascript-questions) repository, `let` and `const` declarations are hoisted but remain uninitialized from the start of the block until the declaration line is executed. This period is called the **Temporal Dead Zone**. Accessing the variable during the TDZ results in a `ReferenceError`.

### ReferenceError on Early Access

Unlike `var`, attempting to read a `let` or `const` variable before its declaration throws an error:

```javascript
function letDemo() {
  // console.log(age); // Uncommenting throws ReferenceError: Cannot access 'age' before initialization
  let age = 30;
  console.log(age); // → 30
}
letDemo();

function constDemo() {
  // console.log(city); // Uncommenting throws ReferenceError
  const city = 'Paris';
  console.log(city); // → Paris
}
constDemo();

```

Note that `const` has the same TDZ rules as `let`, with the additional constraint that it must be initialized at declaration and cannot be reassigned.

## Key Differences Between var, let, and const Hoisting

| Feature | `var` | `let` | `const` |
|---------|-------|-------|---------|
| **Hoisted** | Yes | Yes | Yes |
| **Initialized** | Yes, with `undefined` | No (TDZ) | No (TDZ) |
| **Scope** | Function or global | Block | Block |
| **Early access result** | `undefined` | `ReferenceError` | `ReferenceError` |
| **Reassignment** | Allowed | Allowed | Not allowed |

## Summary

- **JavaScript hoisting** moves all variable declarations to the top of their scope during the creation phase.
- **`var`** declarations are hoisted and initialized with `undefined`, making them accessible (as `undefined`) before their declaration line.
- **`let` and `const`** are hoisted but not initialized, creating a **Temporal Dead Zone** from the start of the block until the declaration. Accessing them during this zone throws a `ReferenceError`.
- According to the [lydiahallie/javascript-questions](https://github.com/lydiahallie/javascript-questions) repository ([`README.md`](https://github.com/lydiahallie/javascript-questions/blob/main/README.md) lines 77, 79, and 3621), understanding these differences is crucial for avoiding common scope-related bugs.

## Frequently Asked Questions

### Are let and const hoisted in JavaScript?

Yes, `let` and `const` are hoisted to the top of their block scope, but unlike `var`, they are not initialized. They remain in the Temporal Dead Zone from the start of the block until the declaration line is executed, which prevents access with a `ReferenceError` rather than returning `undefined`.

### What is the Temporal Dead Zone in JavaScript?

The Temporal Dead Zone (TDZ) is the period between entering a scope and the actual declaration of a `let` or `const` variable. During this time, the variable exists in the scope but is uninitialized. Any attempt to access the variable results in a `ReferenceError`, protecting developers from using variables before they are properly declared.

### Why does var return undefined when hoisted?

`var` declarations are hoisted and automatically initialized with the value `undefined` during the creation phase. This means the variable exists throughout the entire function or global scope immediately upon entering that scope. When you access it before the assignment line, JavaScript returns `undefined` rather than throwing an error, as demonstrated in the [lydiahallie/javascript-questions](https://github.com/lydiahallie/javascript-questions) repository at line 77 of the README.

### Can you access a const variable before declaration?

No, attempting to access a `const` variable before its declaration line throws a `ReferenceError` due to the Temporal Dead Zone. Like `let`, `const` is hoisted but not initialized. Additionally, `const` requires initialization at the moment of declaration and cannot be reassigned, making early access impossible and illegal in JavaScript.