AlgoInsight

Q&A

What is JavaScript hoisting?

By AlgoInsight Team2026-06-07javascript

Overview

Before executing code, the JavaScript engine scans each scope and "hoists" declarations to the top - but how depends on the declaration type. The variable/function name becomes known early, but its value may not be assigned until the original line runs. Misunderstanding this leads to classic bugs.

graph TD
    A[Declaration type] --> B[function declaration: fully hoisted, usable before definition]
    A --> C[var: hoisted, initialized to undefined]
    A --> D[let / const: hoisted but uninitialized → Temporal Dead Zone]
    D --> E[Access before declaration → ReferenceError]
    style D fill:#1e1b4b,color:#fff

Function Declarations: Fully Hoisted

You can call a function declaration before it appears in the code:

greet();                       // "Hello!" - works!
function greet() {
  console.log("Hello!");
}

The entire function definition is hoisted, so it's available throughout its scope.

var: Hoisted but undefined

A var declaration is hoisted, but its assignment stays where it is. Before the assignment line, the variable exists with value undefined:

console.log(x);   // undefined  (not an error - x is hoisted, value not yet set)
var x = 5;
console.log(x);   // 5

// What the engine effectively does:
// var x;            // hoisted declaration, x = undefined
// console.log(x);   // undefined
// x = 5;            // assignment stays here

let and const: Temporal Dead Zone (TDZ)

let and const are also hoisted, but not initialized - accessing them before their declaration throws a ReferenceError. The region from the start of the scope to the declaration is the Temporal Dead Zone:

console.log(y);   // ❌ ReferenceError: Cannot access 'y' before initialization
let y = 10;

This is intentional - it catches use-before-declaration bugs that var silently hides (returning undefined).

Function Expressions Are NOT Fully Hoisted

Only function declarations are fully hoisted. A function assigned to a variable follows that variable's hoisting rules:

greet();                       // ❌ TypeError: greet is not a function
var greet = function () {      // var hoisted as undefined; assignment not yet run
  console.log("Hi");
};
// With const/let it would be a ReferenceError (TDZ) instead.

Summary Table

Declaration Hoisted? Usable before line?
function foo() {} Yes (whole function) Yes
var x Yes (as undefined) Yes, but value is undefined
let / const Yes (uninitialized) No - ReferenceError (TDZ)
function expression / arrow Follows its variable's rule No
class Hoisted but in TDZ No - ReferenceError

Best Practices

Why This Matters in Interviews

Hoisting is a top JavaScript interview topic because it explains many surprising results. Be precise: declarations are hoisted, initializations are not; var → undefined before assignment; let/const → TDZ → ReferenceError; function declarations are fully hoisted but function expressions/arrows are not (they follow their variable). Stating why let/const's TDZ is a feature (catches bugs) shows real understanding rather than memorization.

Common Pitfalls

References

More answers