Dataslope logoDataslope

Loops and Iteration

Repeating work without repeating yourself — `while`, `for`, `for...of`, `for...in`, and the higher-level array methods.

The second great power of control flow — after decisions — is repetition. Almost every interesting program needs to do the same kind of thing many times: process every file in a folder, every row in a table, every pixel on a screen, every customer in a database. That repetition is called iteration, and the syntactic tools for it are called loops.

JavaScript has several kinds of loop. We will learn each one and, just as importantly, when to use which.

The while loop

The simplest loop. While the condition is truthy, run the body. Then check the condition again.

while (condition) {
  // body
}
Code Block
JavaScript ES2023+

Step-by-step trace of what the runtime does:

Stepn beforeconditionaction
111 <= 5 is trueprint, n becomes 2
22trueprint, n becomes 3
33trueprint, n becomes 4
44trueprint, n becomes 5
55trueprint, n becomes 6
666 <= 5 is falseleave the loop

The most important habit: make sure something in the body changes the condition, or your loop will run forever. An infinite loop that you cannot interrupt is one of the few things in JavaScript that will make your tab unresponsive.

The for loop

Often you want to do something N times, or walk an index from some start to some end. The for loop is while with three slots pulled out so they sit together at the top:

for (init; condition; update) {
  // body
}
  • init runs once, before the loop starts.
  • condition is checked before each iteration.
  • update runs at the end of each iteration.
Code Block
JavaScript ES2023+

That i++ is a compact way to write i = i + 1. Combined with the for loop's three slots, it makes counting loops short and readable.

The two loops you just ran are exactly equivalent to writing them with while:

let i = 0;
while (i < 5) {
  console.log("i =", i);
  i++;
}

Same behaviour; just less compactly written.

for...of: walk every element

When you have an array (or any iterable — strings, Sets, Maps, etc.) and you want to do something for each element, for...of is usually the clearest choice. You don't have to manage an index at all.

Code Block
JavaScript ES2023+

If you do need the index alongside the element, use array.entries():

Code Block
JavaScript ES2023+

That [index, color] is destructuring, which we have not formally introduced yet. Treat it as a convenient way to say "give me each pair as two named variables". We will see destructuring properly in the objects chapter.

for...in: walk an object's keys

for...in walks the keys of an object — useful when you want to look at every named property. It is not appropriate for arrays (use for...of for those).

Code Block
JavaScript ES2023+

We will look at objects in detail in their own chapter. For now, remember the shape: for (const key in object).

break and continue

Inside any loop, two special statements let you bail out or skip ahead:

  • break exits the loop entirely.
  • continue skips the rest of the current iteration and starts the next.
Code Block
JavaScript ES2023+

Use these sparingly. Heavy use of break/continue is often a sign that the loop is doing too many things at once and could be split into smaller helpers.

The "loop and accumulate" pattern, revisited

We saw this in the Computational thinking chapter. It is the single most common shape of loop in real code: start with a blank result, walk a list, update the result.

Code Block
JavaScript ES2023+

Notice that each example is the same pattern: initialise; loop; update. Once you see this shape, you see it everywhere.

Higher-level alternatives: forEach, map, filter, reduce

For the very common pattern of "do something with every element of an array", arrays come with built-in methods that often read better than a hand-written loop. We will dedicate an entire later chapter to these, but here is a small taste:

Code Block
JavaScript ES2023+

These are the functional style of iteration: instead of writing the loop, you describe what you want done with each element, and JavaScript runs the loop for you.

When learning, write the explicit for loop first; then, once you are comfortable, switch to map/filter/reduce where they make the intent clearer.

Nested loops

A loop inside a loop is called a nested loop. The inner loop runs to completion for each iteration of the outer loop. This is how you generate combinations, walk a grid, or compare every item to every other item.

Code Block
JavaScript ES2023+

Be mindful of cost: nesting an N-element loop inside another N-element loop runs the inner body N×N times. For N=10 that's 100 — fine. For N=10,000 that's 100,000,000 — possibly too slow.

Beware the infinite loop

Always ask: how does this loop end? Common mistakes:

// (a) Forgetting to update the counter
let i = 0;
while (i < 5) {
  console.log(i);
  // Oops — forgot i++. This runs forever.
}

// (b) Updating the wrong way
for (let i = 0; i < 10; i--) {
  console.log(i);
  // i goes 0, -1, -2, ... forever.
}

If your tab freezes when you press Run, your loop almost certainly forgot to terminate. Stop the runtime, find the loop, fix the update.

Step-by-step execution diagram

Mentally tracing a loop is a skill. Here is a flowchart for the classic for (let i = 0; i < N; i++) { ... }:

Picture this in your head every time you write a for loop. Half the loop bugs in the world come from forgetting where each piece goes in this cycle.

Challenge

Challenge
JavaScript ES2023+
FizzBuzz

Write a function fizzbuzz(n) that returns an array of n strings. For positions 1 through n:

  • If the position is divisible by 15, the string is "FizzBuzz".
  • Otherwise, if it's divisible by 3, the string is "Fizz".
  • Otherwise, if it's divisible by 5, the string is "Buzz".
  • Otherwise, the string is the position number, converted to a string (e.g. "7").

For example, fizzbuzz(5) should return ["1", "2", "Fizz", "4", "Buzz"].

Implement it with a for loop and an array you build up with .push().


QuestionSelect one

Which loop is the cleanest way to do something for every element of an array, when you don't need the index?

A while loop with a manual counter

A for (let i = 0; i < arr.length; i++) loop

A for...in loop

A for...of loop: for (const item of arr) { ... }

On this page