Hoisting
Why some code works before it appears. Declarations move to the top.
What is Hoisting?
JavaScript moves declarations to the top of their scope before executing.
What you write:
greet();
function greet() {
console.log("Hello!");
}What the engine sees:
function greet() {
console.log("Hello!");
}
greet(); // ✓ works!💡 "Hoisting" isn't literally moving code. The engine scans declarations first (creation phase), then executes. It just appears like declarations moved up.
Function Hoisting
Function declarations are fully hoisted — usable anywhere in their scope.
// ✓ Works — function declarations are hoisted:
const result = add(2, 3); // 5
function add(a, b) {
return a + b;
}
// ✗ Fails — function expressions are NOT hoisted:
const result2 = multiply(2, 3); // TypeError!
const multiply = function(a, b) {
return a * b;
};
// ✗ Also fails — arrow functions:
const result3 = divide(10, 2); // TypeError!
const divide = (a, b) => a / b;✓ Hoisted (fully)
function name() {}
✗ NOT hoisted
const fn = function() {}
const fn = () => {}
var Hoisting
var declarations are hoisted but NOT their assignments.
console.log(x); // undefined (not ReferenceError!) var x = 5; console.log(x); // 5
var is hoisted with a value of undefined. The assignment (= 5) stays in place and runs during execution.
Temporal Dead Zone
let and const exist but can't be accessed until their declaration.
// The Temporal Dead Zone (TDZ):
{
// ┌── TDZ for 'x' starts ──┐
// │ │
console.log(x); // ReferenceError!
// │ │
// └── TDZ for 'x' ends ─────┘
let x = 10; // ← x is now initialized
console.log(x); // 10 ✓
}
// Same for const:
console.log(PI); // ReferenceError!
const PI = 3.14;
console.log(PI); // 3.14 ✓Timeline of a let/const variable:
↑ declaration reached
Hoisting Precedence
What happens when names collide.
// Function declarations beat var declarations:
var foo = "variable";
function foo() { return "function"; }
console.log(typeof foo); // "function"
// Function was hoisted above the var
// But assignment wins in execution:
var bar = "I win";
function bar() { return "function"; }
console.log(bar); // "I win"
// After execution, the assignment overwrites
// Function declarations beat each other (last wins):
function x() { return 1; }
function x() { return 2; }
x(); // 2 — last declaration wins💡 Best practice: Use const/let and avoid relying on hoisting. Declare everything before use. Problems with hoisting are why let/const were created.
FAQ
Common questions about hoisting.