What hoisting really is
A consequence of Phase 1, not magic.
- Not a physical move — declarations stay where they are in source.
- Phase 1 (Memory Creation) scans the entire code and allocates memory.
- Only declarations are hoisted — assignments stay in Phase 2.
- Happens in every Execution Context (global and function scope).
var vs function declaration
The two classic behaviours.
var x = 10→xhoisted as undefined; usable before the line.function foo() {}→ hoisted as entire function body; callable before the line.- Same-name collision → function wins during memory phase; later var assignment overwrites.
- Duplicate function declarations → last one wins.
Function expressions + arrows
Treated as variables, not functions.
var fn = function() {}/var fn = () => {}→ hoisted asundefined.- Calling before the assignment line → TypeError: is not a function.
- Why TypeError? You’re invoking
undefined(). - Switch to
let/constand the error becomes ReferenceError (TDZ).
let, const & class
Hoisted, but into the Temporal Dead Zone.
let/const/classare hoisted — but unreachable until the declaration line runs.- Accessing them in the TDZ →
ReferenceError: Cannot access 'x' before initialization. - Different from
undefined(var) and from “not defined” (never declared at all). - Classes share the TDZ rule —
new Animal()before the class line throws too.
Three errors, three meanings
Which one fires, and why.
- undefined — var was hoisted, no value yet. (
console.log(x)beforevar x = 7.) - TypeError: is not a function — variable exists, but holds something non-callable.
- ReferenceError: x is not defined — the identifier was never declared at all.
- ReferenceError: Cannot access before initialization — let/const/class in TDZ.
Tricky corners
The bits interviewers love.
- Named function expression — the name is usable inside the function only (good for recursion).
function a() {}afterreturninside a function still hoists — shadows globals.- Block-scoped
functiondeclarations are hoisted only within the block in modern strict mode. console.log(fn)prints the whole function body — a live proof of Phase 1.
Comments
Comments are disabled in this environment. Set
PUBLIC_GISCUS_REPO,PUBLIC_GISCUS_REPO_ID, andPUBLIC_GISCUS_CATEGORY_IDto enable.