Hoisting & Temporal Dead Zone

When learning JavaScript, two of the most confusing concepts are hoisting and the Temporal Dead Zone (TDZ). In this article, we’ll break them down with simple explanations and code examples.

What is Hoisting?

Hoisting is JavaScript’s behavior of moving variable and function declarations to the top of their scope before code execution.

Important: only declarations are hoisted, not assignments.

Example with functions

greet();

function greet() {
  console.log("Hello from hoisting!");
}

✅ This works because function declarations are fully hoisted to the top of the scope.

Example with var variables

console.log(name); // undefined
var name = "Elias";

➡️ What happened here? Internally, the engine treats it like this:

var name; // hoisted
console.log(name); // undefined
name = "Elias";

That’s why it doesn’t throw an error but logs undefined.

let and const change the rules

With ES6, let and const introduced the Temporal Dead Zone (TDZ).

console.log(lastName); // ❌ ReferenceError
let lastName = "Delgado";

Unlike var, accessing the variable before its declaration throws an error.

The Temporal Dead Zone (TDZ)

The TDZ is the period between the start of a scope and the point where a variable declared with let or const is initialized. During this time, the variable exists but cannot be accessed.

{
  // 'x' exists in this block
  // but is in the TDZ until initialized
  console.log(x); // ❌ ReferenceError
  let x = 10;
  console.log(x); // ✅ 10
}

Example with const

const behaves the same as let regarding the TDZ but also requires immediate initialization:

console.log(pi); // ❌ ReferenceError
const pi = 3.1416;

Why does the TDZ exist?

The TDZ was introduced to avoid logical errors and make code more predictable.

Consider this with var:

function example() {
  console.log(message); // undefined
  if (false) {
    var message = "Hello!";
  }
}

👉 This can lead to hard-to-find bugs. With let or const, the engine won’t let you access the variable too early:

function example() {
  console.log(message); // ❌ ReferenceError
  if (false) {
    let message = "Hello!";
  }
}

✅ Much safer.

Quick recap

  • Function declarations: fully hoisted (can be used before definition).
  • var variables: hoisted as undefined.
  • let and const variables: exist in the TDZ until initialized.
  • TDZ prevents silent bugs and makes code more reliable.

Conclusion

Hoisting is one of those JavaScript quirks that often confuse beginners, but once you understand how it works along with the Temporal Dead Zone, your code becomes more predictable and safe.

👉 Practical rule of thumb:

  • Always use let and const (prefer const by default).
  • Avoid var to prevent unexpected behavior.