Programming Language
JavaScript
Hoisting

JavaScript Hoisting and Temporal Dead Zone (TDZ)

What is Hoisting?

Hoisting is JavaScript's behavior of moving declarations to the top of their scope before execution. This applies to variables (var, let, const) and functions.


Function Hoisting

Function declarations are hoisted with their definitions, meaning they can be called before they are defined.

Example:

sayHello(); // Works fine
 
function sayHello() {
    console.log("Hello, World!");
}

Function Expressions Are Not Hoisted

Only function declarations are hoisted, not function expressions.

hello(); // Error: Cannot access 'hello' before initialization
 
const hello = function() {
    console.log("Hi!");
};

Use Case:

Use function declarations when you need to call a function before its definition in the file (e.g., utility functions in large applications).


Variable Hoisting

var Hoisting

var declarations are hoisted but not initialized, so they exist but hold undefined.

console.log(a); // undefined
var a = 10;
console.log(a); // 10

This happens because JavaScript interprets it like this:

var a;
console.log(a); // undefined
 
a = 10;
console.log(a); // 10

Use Case:

Using var can lead to unintended behavior, such as using an uninitialized variable. Prefer let or const to avoid this.

let and const Hoisting (TDZ)

Variables declared with let and const are also hoisted, but they remain in the Temporal Dead Zone (TDZ) until the declaration is encountered.

console.log(x); // Error: Cannot access 'x' before initialization
let x = 20;
console.log(y); // Error: Cannot access 'y' before initialization
const y = 30;

Use Case:

Using let and const ensures variables are only accessible after they have been initialized, making code more predictable.


Temporal Dead Zone (TDZ)

The Temporal Dead Zone (TDZ) is the period between the start of the execution context and the point where the variable is declared.

Example of TDZ:

console.log(value); // Error: Cannot access 'value' before initialization
let value = 42;
console.log(value); // 42

The TDZ exists from the beginning of the block until the variable's declaration is encountered.

Use Case:

Understanding TDZ helps prevent ReferenceErrors and ensures variables are used only when they are ready.


Avoiding TDZ Issues

To avoid TDZ-related errors:

  1. Declare variables at the top of their scope.
  2. Initialize variables immediately when possible.
  3. Use const for constants, and let for variables that need reassignment.
// Good practice
let count = 0;
const maxLimit = 100;

Advanced Hoisting Examples

Hoisting in Functions

function outer() {
    console.log(inner()); // Works fine
    function inner() {
        return "Inside Inner Function";
    }
}
outer();

Hoisting in Blocks

Variables declared with let and const are not hoisted beyond their block scope.

{
    console.log(a); // Error: Cannot access 'a' before initialization
    let a = 5;
}

Use Case:

Use block scoping to limit variable access within specific areas of code, preventing unintended access.


Summary

  • Hoisting moves declarations to the top of their scope.
  • Functions are fully hoisted, but function expressions are not.
  • var is hoisted but initialized as undefined.
  • let and const are hoisted but stay in the TDZ until initialized.
  • Accessing a let or const variable before declaration causes a ReferenceError.
  • Understanding hoisting and TDZ helps write clean and predictable JavaScript code.

By mastering these concepts, you can avoid common pitfalls and write more reliable JavaScript code.