Hoisting in JS
Part 1: What is Hoisting?
Hoisting is JavaScript's behaviour of moving declarations to the top of their scope during the memory creation phase — before any code actually runs. The code doesn't physically move, but the engine processes declarations first.
Only declarations are hoisted, not initialisations. The name is stored, but the value is not.
Without hoisting, this would fail — but it doesn't
javascript
console.log(name); // undefined (not an error!)
var name = "Arjun";
console.log(name); // Arjun
// What the engine sees (conceptually):
var name; // declaration hoisted to top
console.log(name); // undefined (declared but no value yet)
name = "Arjun"; // assignment stays in place
console.log(name); // ArjunPart 2: var, let, const — Different Hoisting Behaviour
var — hoisted and initialised as undefined
javascript
console.log(x); // undefined (no error)
var x = 10;
console.log(x); // 10
// var declarations are hoisted AND given the value undefined
// so reading them before assignment gives undefined, not an errorlet and const — hoisted but NOT initialised (TDZ)
let and const are hoisted but placed in the Temporal Dead Zone (TDZ). Accessing them before their declaration throws a ReferenceError.
javascript
console.log(y); // ❌ ReferenceError: Cannot access 'y' before initialization
let y = 20;
console.log(z); // ❌ ReferenceError
const z = 30;
// The TDZ is the period between the start of the scope
// and the line where the variable is declared.
// Accessing a variable in its TDZ throws an error.Side-by-side comparison
var behaviour
javascript
// ✅ No error
console.log(a); // undefined
var a = 1;
console.log(a); // 1let/const behaviour
javascript
// ❌ ReferenceError
console.log(b);
let b = 1;
console.log(b);Part 3: Function Hoisting
Function declarations are fully hoisted — the entire function body is stored in memory during the memory phase. This means you can call a function before its definition in the file.
Function declaration — fully hoisted
javascript
greet(); // ✅ Works! Output: Hello!
function greet() {
console.log("Hello!");
}
// The entire function is hoisted, so calling it before
// the definition is perfectly valid.Function expression — NOT hoisted (follows variable rules)
javascript
greet(); // ❌ TypeError: greet is not a function
var greet = function() {
console.log("Hello!");
};
// 'greet' is hoisted as undefined (it's a var)
// calling undefined() → TypeError
// With let:
sayHi(); // ❌ ReferenceError: Cannot access 'sayHi' before initialization
let sayHi = function() { console.log("Hi!"); };Arrow functions — same as function expressions
javascript
hello(); // ❌ ReferenceError
const hello = () => {
console.log("Hello!");
};
// Arrow functions assigned to const/let are in the TDZ
// until the line they're declared — same as any let/const