← Back to Chapters

JavaScript Hoisting

? JavaScript Hoisting

? Quick Overview

Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope (the current script or function). Variables and function declarations are processed before any code is executed, which affects how and when you can safely use them.

? Key Concepts

  • Only declarations are hoisted, not initializations.
  • var variables are hoisted and initialized with undefined.
  • let and const are hoisted but not initialized and stay in the temporal dead zone (TDZ) until their declaration line.
  • Function declarations are fully hoisted and can be called before their definition.
  • Function expressions (e.g., using var) are not safely callable before the assignment line.

? Syntax and Theory

When a JavaScript file or function runs, the engine first performs a creation phase, where it scans for variable and function declarations. During this phase:

  • var declarations are created and set to undefined.
  • let and const declarations are created but left uninitialized in the TDZ.
  • Function declarations are created with their full function body available.

In the execution phase, JavaScript runs line by line. Accessing a var before its declaration gives undefined, while accessing let/const before their declaration throws a ReferenceError.

? Code Examples

? Variable Hoisting with var

? View Code Example
console.log(x); // undefined
var x = 5;
console.log(x); // 5

? Temporal Dead Zone with let

? View Code Example
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;
console.log(y); // 10

? Function Declaration Hoisting

? View Code Example
greet(); // "Hello there!"

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

? Function Expression and Hoisting

? View Code Example
sayHi(); // TypeError: sayHi is not a function

var sayHi = function() {
console.log("Hi!");
};

? Hoisting with const

? View Code Example
console.log(z); // ReferenceError: Cannot access 'z' before initialization
const z = 10;
console.log(z); // 10

? Live Output & Explanation

? What Actually Happens?

  • var example: In the creation phase, x is created and set to undefined. So the first console.log(x) prints undefined. After the assignment, it prints 5.
  • let and const examples: y and z exist in memory but are uninitialized in the TDZ. Accessing them before their declaration line throws a ReferenceError.
  • Function declaration: The entire greet function is hoisted, so it can be called before its definition.
  • Function expression: Only the variable sayHi is hoisted and set to undefined. When you try to call sayHi() before the assignment, you're effectively doing undefined(), which causes a TypeError.

? Tips & Best Practices

  • Remember that only declarations are hoisted, not initializations.
  • Prefer using let and const to avoid accidental hoisting-related bugs.
  • Declare variables at the top of their scope to make hoisting behavior explicit.
  • Use function declarations when you intentionally want to call functions before their definition.
  • Be careful with function expressions: do not rely on them before the assignment line.

? Try It Yourself / Practice Tasks

  • Declare a var variable and log it before and after the declaration. Observe the output.
  • Repeat the same experiment using let and const and note the difference.
  • Create a function declaration and call it both before and after its definition.
  • Create a function expression stored in var and try calling it before and after assignment.
  • Rewrite a small program so that all declarations appear at the top of their scope to reduce hoisting confusion.