JS Sketchbooksee JavaScript think ✏️
← back to phase 5

5.2 — Hoisting, demystified

Lesson 1.4 called var "old and leaky" and promised the full story in Phase 5. This is that lesson. The word you'll hear in every interview is hoisting — and after 5.1 you already know the machinery behind it: pass 1 registers names before any line runs.

Today's whole lesson is one table: the three declaration kinds get three different registrations. var → name + undefined (reads early, silently wrong). let/const → name registered but untouchable until their line (the temporal dead zone — reads throw, loudly).

Function declarations → registered complete. Learn the table and every hoisting puzzle ever written becomes arithmetic.

watch it happen
console.log(a);
var a = 1;

console.log(b);
let b = 2;

Pass 1 sweeps this code and registers both names — but look at the registry: a (var) holds the placeholder undefined, while b (let) is marked UNINITIALIZED. Both names exist before any line runs. What differs is what touching them early DOES.

the registry after pass 1 — three kinds, three treatmentsnamedeclared withregistered asavarundefinedblet⛔ uninitialized⛔ = the temporal dead zone — using the name before its line THROWSsame pass 1, DIFFERENT registrations — this table is the whole lessonconsole(nothing yet)
under the hood

The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”

The full table, worth memorizing: function f() {} → registered complete. var x → registered as undefined. let/const → registered uninitialized (TDZ; reads throw ReferenceError).

And var has a second leak this table explains: it ignores block scope. A var inside an if registers on the whole function's context — escaping the braces that 3.5 said contain things.

Why does var still exist? Compatibility — the web never breaks old pages. Your rule stands exactly as 1.4 stated it: const by default, let when reassigning, var only when reading old code. Now you can also explain the rule, which is what interviews actually test.

💼 On the job — interviewers phrase this a dozen ways — "is let hoisted?" is the trap. The precise answer: yes, all declarations are registered in pass 1 — but let/const are registered uninitialized, so unlike var they throw instead of reading undefined. That sentence separates memorizers from understanders.

your turn

⌨️ early birds and patient variables

Demonstrate mastery of both hoisting behaviors in one small program: a function declaration you deliberately call early, and a function expression you correctly call only after its line.

requirements:

  • Very first line: call stretch() — its function DECLARATION lives at the bottom of the file and returns "10 min". Print the returned value.
  • Then define wake as a const ARROW function returning "6am", and print wake() — called after its line, as expressions require.

when you press RUN, the console must show exactly:

10 min
6am

✏️ Quick check 1

Type exactly what this prints:

console.log(x);
var x = 3;

✏️ Quick check 2

This code throws. Type the ERROR NAME (the part before the colon):

console.log(y);
let y = 3;

✏️ Quick check 3

Which kind can be safely CALLED above its line — a function declaration or a function expression? Type one word: declaration or expression.

teach it back

🗣️ Now teach it back

The interview classic: “Is let hoisted?” Give the precise answer — covering what pass 1 does to var, let/const, and function declarations, and what the temporal dead zone actually is.

Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.

a few sentences, minimum — you’ve got this
to remember
All declarations register in pass 1 — differently: var → undefined; let/const → uninitialized (TDZ, reads THROW); function declarations → complete.
The TDZ error is a feature: loud and local beats var’s silent undefined leaking into calculations far away.
Function expressions are variables holding functions — they hoist by their variable’s rules. Ask “what kind of declaration?”, never “is it a function?”.