Looping with forEach

You already know two ways to loop over an array. for...of visits each element, and the counted for loop gives you each index. Arrays also have a method called forEach. You give it a callback, and it calls that function once for each element:

const dishes = ["soup", "pasta", "cake"];

dishes.forEach(dish => {
  console.log(dish);
});

Output:

soup
pasta
cake

This is the callback idea from the Functions section. The forEach method does the looping, and your arrow function says what to do with each element.

The callback can take a second parameter. forEach passes the element's index there:

<!-- continues -->
dishes.forEach((dish, i) => {
  console.log(`${i + 1}. ${dish}`);
});

Output:

1. soup
2. pasta
3. cake

The index starts at 0, so i + 1 gives the numbers people expect: 1, 2, 3.

The index is also useful when two arrays belong together. Here the price of dishes[i] is stored in prices[i]:

<!-- continues -->
const prices = [4, 9, 5];
dishes.forEach((dish, i) => {
  console.log(`${dish} costs ${prices[i]}`);
});

Output:

soup costs 4
pasta costs 9
cake costs 5

Arrays that line up by index like this are called parallel arrays. They work, but it is easy to change one array and forget the other. The Objects section shows a better way to keep a dish and its price together.

So which loop should you use?

  • for...of when you only need the elements. You can stop it early with break.
  • forEach when you want each element together with its index.
  • the counted for loop when the index controls the work, for example to go backwards or to skip every second element.

forEach cannot stop early. A break inside its callback is not allowed:

[1, 2, 3].forEach(n => {
  if (n === 2) break;
  console.log(n);
});

Output:

/box/index.js:2
  if (n === 2) break;
               ^^^^^

SyntaxError: Illegal break statement

The program does not even start. break only works directly inside a loop, and the callback is a function, not a loop. When you need to stop early, use for...of.

In the exercise, print a numbered menu line for each dish with its price, then the total.