Skip to content
Lesson 7 of 15

Step 1 of 5 · Reading · ~4 min

Learn

Control Flow

Loops and Iteration

A loop repeats a block of code. By the end of this lesson you can pick the right loop for the job, accumulate a result across iterations, track a running best, and spot an off-by-one error before it ships. TypeScript has every JavaScript loop, with the loop variable's type inferred for free.

The classic for loop

for (let i = 0; i < 5; i++) {
    console.log(i); // 0 1 2 3 4
}

Three clauses separated by semicolons: initialize (let i = 0), keep going while true (i < 5), step after each pass (i++). i is inferred as number; annotating it is legal but noise. Use for when you know how many times to repeat, or need the index.

while

let value: number = 100;
let bits: number = 0;
while (value > 0) {
    value = Math.floor(value / 2);
    bits++;
}
console.log(bits); // 7: how many halvings it takes to reach 0

The condition is checked before every pass, including the first, so the body may run zero times. Reach for while when you do not know the number of passes in advance. The danger is a condition that never becomes false: if nothing inside the loop moves value toward 0, the program hangs. Before writing a while, say which variable changes and why that eventually ends it.

for...of: the values

const heights: number[] = [160, 172, 181, 168];

for (const h of heights) {
    console.log(h); // 160, 172, 181, 168: h is inferred as number
}

for...in: the keys (the trap)

for...in walks KEYS, and for arrays the keys are strings:

for (const k in heights) {
    console.log(k);       // "0", "1", "2", "3": strings, not the values
    // k + 1 is "01", string concatenation, not arithmetic
}

Use for...of for arrays, and Object.keys() for the keys of a plain object. When you need both position and value, use .entries(), which hands out one [index, value] pair per pass. Writing const [i, h] unpacks the pair into two names (this is called destructuring; the arrays lesson covers it fully):

for (const [i, h] of heights.entries()) {
    console.log(i, h);
}

heights.forEach((h, i) => console.log(i, h)) also passes (element, index) to a small inline function, but you cannot break out of it.

Controlling a loop

break leaves the loop immediately; continue skips to the next pass.

for (const h of heights) {
    if (h < 165) continue;       // skip the short ones
    if (h > 180) break;          // stop at the first very tall one
    console.log(h);
}

Accumulating and tracking a best

Two patterns cover most loops. An accumulator starts at an identity value and folds each element in. A running best starts at the first value and replaces itself when something beats it:

let sum: number = 0;
let tallest: number = heights[0];
for (const h of heights) {
    sum += h;
    if (h > tallest) {
        tallest = h;
    }
}
console.log(sum, tallest); // 681 181

Start the best at a value from the data (or -Infinity), not at 0: with all-negative data, 0 would win without being in the data.

The trap: off-by-one boundaries

To add 1 through N you must include N, so the condition is i <= n:

for (let i = 1; i < n; i++)  { sum += i; } // WRONG: stops at n - 1
for (let i = 1; i <= n; i++) { sum += i; } // right: includes n

For n = 5 the first adds 10 instead of 15. Before trusting a loop, check its first pass, its last pass, and what happens when it should run zero times.

Common mistakes

  • A while whose variable never changes. The program hangs until the grader times it out.
  • for...in on an array. You get string indices, and k + 1 glues text.
  • Updating the best after the loop instead of inside it. The final value is whatever the last pass left.
  • Counting a pass too many or too few. Decide whether the starting state counts as a step before you write the counter.

Your exercise

Explore a famous number sequence: repeat a simple rule until a value reaches 1, counting the steps and remembering the largest value seen. The starter declares the variables. Decide up front whether the final arrival at 1 is a step, and remember that the largest value can be the starting value itself.

Up nextFunction TypesFunctions

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…