Hoisting in JavaScript
Hoisting
Hoisting is JavaScript's default behavior of moving function and variable declarations to the top of their scope before code execution. It means, no matter where functions and variables are declared, they are moved to the top of their scope regardless of whether their scope is global or local.
x = 10;
y = 20;
console.log(x+y); // 30
var x;
var y;
Hoisting is not possible with variable initializations, only declarations are hoisted.
console.log(x+y); // undefined
var x = 10;
var y = 20;
Like variable hoisting, JavaScript compiler moves the function definition at the top.
console.log(Sum(10, 20)); // 30
var Total = function Sum(x, y) {
return x + y;
}
JavaScript compiler does not move function expression at the top. So, function hoisting in JavaScript is only possible with definition.
console.log(Sum(10, 20)); // 30
function Sum(x, y) {
return x + y;
}
let and const - NOT Hoisted
Variables declared with let and const are hoisted to the top of their block but are NOT initialized. Accessing them before declaration causes a ReferenceError - this is called the Temporal Dead Zone (TDZ).
// var - hoisted and initialized as undefined
console.log(a); // undefined (no error)
var a = 5;
// let - hoisted but NOT initialized (Temporal Dead Zone)
// console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
// const - same as let, must be initialized at declaration
// console.log(c); // ReferenceError
const c = 15;
// Practical example of TDZ
function checkTDZ() {
// TDZ starts here for 'x'
console.log(typeof x); // ReferenceError in strict mode
let x = 'hello'; // TDZ ends here
}
Class Hoisting
Like let and const, class declarations are hoisted but not initialized. You cannot use a class before it is declared.
// This will throw ReferenceError
// const obj = new Animal(); // ReferenceError
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a sound.`;
}
}
// This works fine - class is declared before use
const dog = new Animal('Dog');
console.log(dog.speak()); // Dog makes a sound.
Hoisting Summary Table
| Declaration | Hoisted? | Initialized? | Accessible Before Declaration? |
|---|---|---|---|
var | Yes | Yes (undefined) | Yes (returns undefined) |
let | Yes | No (TDZ) | No (ReferenceError) |
const | Yes | No (TDZ) | No (ReferenceError) |
| function declaration | Yes | Yes (full body) | Yes |
| function expression | Partial (var only) | No | No (TypeError) |
| class | Yes | No (TDZ) | No (ReferenceError) |
- var declarations are hoisted and initialized as undefined - accessing before declaration returns undefined, not an error.
- let and const are hoisted but NOT initialized - accessing them before declaration throws a ReferenceError (Temporal Dead Zone).
- Function declarations are fully hoisted - you can call them before they appear in code.
- Function expressions (var fn = function(){}) are NOT fully hoisted - only the var declaration is hoisted.
- Class declarations are in the TDZ - always declare classes before using them.
- Prefer let and const over var to avoid confusing hoisting behavior.