JS Sketchbooksee JavaScript think ✏️
← back to phase 5

5.9 — Checkpoint: the explain-it-all interview

Checkpoint — and this one has a special shape, because Phase 5's material is the JavaScript interview. Hoisting puzzles, this traps, prototype questions: they're not trivia, they're checks for exactly the machinery you now own — two passes, call sites, ropes, chains, reachability, falling sparks.

Today: three notorious snippets replayed with your tools, a battery of typed checks, and two builds — one of which is, quietly, the heart of every test runner ever written. No new concepts. Just proof.

watch it happen
// snippet A — hoisting
console.log(a);
var a = 1;
console.log(b);
let b = 2;

// snippet B — this
const obj = {
  n: "X",
  get() { return this.n; },
};
const g = obj.get;
// obj.get() vs g() ?

// snippet C — the chain
const base = { hi: "yo" };
const kid = Object.create(base);
// kid.hi ?  Object.keys(kid) ?

The three snippet families that appear in some form in nearly every JavaScript interview. The untrained answer them by memory and get one wrong. You’ll answer by SIMULATION — running the machinery in your head. That difference is the whole phase.

the interview boardA · hoisting — 5.1/5.2B · this — 5.4C · prototypes — 5.5three famous traps. You now own the machinery behind every one
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.”

💼 On the job — why interviewers ask these: not to see if you memorized outcomes, but to hear which model you reason with. "undefined because hoisting" is a memorizer's answer. "Pass one registered the name with undefined; the assignment is pass-two work" is an understander's answer. Same output, different career.

The runner you're about to write (part 2) is genuinely the core loop of Vitest and Playwright's runner. Each test is a function. The framework calls it inside a try. A thrown assertion becomes a red result with the error's message. The loop continues. When you meet test('name', fn) in Phase 10, you'll recognize an old friend.

And the chainable class (part 1) is the fluent style behind locator.filter(...).first() and every builder API: methods that return this so calls read as sentences. Two small builds, two large habits.

your turn

⌨️ part 1 — the chainable scorekeeper

Build a class whose method calls CHAIN — s.add(5).add(7) — the fluent style you’ll meet all over Playwright. The trick is one line: a method that returns the object it was called on.

requirements:

  • A class ScoreKeeper: its constructor sets this.points = 0.
  • A method add(n) that increases this.points by n — and then returns the keeper itself, so another call can hang off the result.
  • Make one instance, chain add(5).add(7) in a single expression, then print points.

when you press RUN, the console must show exactly:

12

⌨️ part 2 — the heart of a test runner

Write the ten lines every test framework is built around: run a function, catch its failure, report either way — and never let one failure stop the next run.

requirements:

  • A function attempt(fn): inside a try, call fn() and RETURN its result. In the catch, return "failed: " + the error's message.
  • Two candidate functions: safe, an arrow returning 7; and risky, an arrow that THROWS a new Error with message "nope".
  • Print attempt(safe), then attempt(risky) — proof that the failure was contained and life went on.

when you press RUN, the console must show exactly:

7
failed: nope

✏️ Quick check 1

Pass 1 then pass 2 — type exactly what this prints:

console.log(crew);
var crew = "alpha";

✏️ Quick check 2

This throws — type the ERROR NAME:

console.log(mode);
const mode = "dark";

✏️ Quick check 3

Read the call site — type exactly what this prints:

const mic = {
  id: "M1",
  tag() { return this.id; },
};
const t = mic.tag.bind(mic);
console.log(t());

✏️ Quick check 4

Walk the chain — type exactly what the FIRST console.log line prints:

const tool = { grip: "firm" };
const axe = Object.create(tool);
console.log(axe.grip);
console.log(Object.keys(axe).length);

✏️ Quick check 5

References, one last time — type exactly what this prints:

const a = { v: 1 };
const b = { v: 1 };
console.log(a === b);
teach it back

🗣️ Now teach it back

The mock interview, for real: in your own words, explain (1) what hoisting actually is, (2) how this is decided, (3) what a closure is precisely, and (4) how property lookup works on objects. Four short paragraphs — as if the interviewer is across the table.

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
Answer by SIMULATION, not memory: run pass 1/pass 2 for hoisting; read the call site for this; walk the chain for properties.
The four-sentence kit: hoisting = two passes · this = call site · closure = kept context · lookup = the climb.
You built a fluent (return this) class and a real test-runner core (try → run fn → catch → report → continue). Phase 10 will feel like coming home.
next: 6.1 Sync vs async →