Crux Read four small programs and trace them by hand: predict loop counts and outputs, spot an off-by-one boundary, and reason about short-circuit evaluation as chained conditional jumps.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at middle altitude — in the sky
◷ 14 min
The only reliable way to know what a branch or loop does is to trace it the way the CPU does: follow the program counter and the variables, one step at a time. Read each snippet, predict the outcome by hand, then check yourself.
Goal
Practise the core skill of the unit: step through conditionals and loops by hand, count iterations exactly, find the off-by-one that flips a boundary, and reason about short-circuit evaluation as the chained conditional jumps it compiles to.
Snippet 1 — count the iterations
let count = 0;let i = 1;while (i <= 5) { // note: <= , not < count++; i++;}// what is count?
Quiz
Completed
What is the final value of count?
Heads-up The test is i <= 5, which includes 5, so the body runs for i = 1..5 (five times). It would run four times only if the test were i < 5.
Heads-up When i becomes 6 the while test i <= 5 is false, so the body does not run for 6. The backward jump is not taken and the loop exits before incrementing count again.
Heads-up i++ runs every iteration, so the compared value changes and the test eventually fails at i = 6. The loop terminates.
Snippet 2 — the off-by-one boundary
const a = [10, 20, 30]; // length 3, valid indices 0,1,2let i = 0;while (i <= a.length) { // <= length, not < length console.log(a[i]); i++;}
Quiz
Completed
How many times does the loop body run, and what is the bug?
Heads-up i <= a.length is true for i = 0,1,2 and also for i = 3 (since 3 <= 3). The body runs four times and reads a[3], which does not exist.
Heads-up i++ runs each pass, so i reaches 3 and then 4; at i = 4 the test 4 <= 3 is false and the loop exits. It is not infinite — it just runs one time too many.
Heads-up The test compares i to a.length, it does not index with it. The first test is 0 <= 3 (true), so the body runs; the boundary error is at the end, not the start.
Snippet 3 — short-circuit as chained jumps
function check(user) { // && stops at the first falsy operand if (user && user.active && user.age >= 18) { return "allowed"; } return "denied";}check(null); // user is null
Quiz
Completed
check(null) returns 'denied'. Why does user.active never get evaluated, in machine-level terms?
Heads-up && short-circuits: it stops at the first falsy operand. Reading user.active on a null user would actually throw — short-circuit is exactly what prevents that, by jumping past those reads.
Heads-up Operands are evaluated left-to-right. user is tested first; being null (falsy), the conditional jump skips the rest before user.active or user.age is ever read.
Heads-up It is never evaluated. The conditional jump after testing user transfers control past those reads entirely, which is why no error is thrown on the null user.
Snippet 4 — nested loop and conditional
let sum = 0;for (let i = 0; i < 3; i++) { // outer: i = 0,1,2 for (let j = 0; j < 3; j++) { // inner: j = 0,1,2 if (i === j) { // only the diagonal sum += 1; } }}// what is sum?
Quiz
Completed
What is the final value of sum?
Heads-up The inner body runs 9 times, but sum += 1 is guarded by if (i === j). Only the 3 diagonal pairs pass the test; the other 6 take the skip jump.
Heads-up It is the reverse: only the diagonal pairs (where i === j) increment sum. The 6 off-diagonal pairs are skipped by the conditional jump.
Heads-up i === j is true once per outer iteration, and there are 3 outer iterations, so it is true 3 times: (0,0), (1,1), (2,2).
Recap
Tracing by hand is the whole skill. A loop’s count is exactly how many times its test stays true — and the boundary operator (< vs <=) is where off-by-one bugs live, here reading one element past the end of a 3-element array. Short-circuit && compiles to chained conditional jumps that bail to the false path the moment an operand is falsy, which is why later operands are never even read (and why a null check guards the reads after it). Nested loops multiply iteration counts, but a guarding if still only fires when its own condition holds. When in doubt, walk the program counter and the variables one step at a time.