Looping and Iterating - Array forEach

Beginner JavaScript

Enjoy these notes? Want to Slam Dunk JavaScript?

These are notes based on my Beginner JavaScript Video Course. It's a fun, exercise heavy approach to learning Modern JavaScript from scratch.

Use the code BEGINNERJS for an extra $10 off.

BeginnerJavaScript.com

Let's talk about looping and iterating. There are a few different ways to loop in JavaScript and we will cover them all.

The most common way you are going to loop over something in JavaScript is looping over an array. Most of the looping also works the exact same way.

We will use a method that lives on the array, and we will pass it a callback, just like in the previous video.

The callback function will run once for every item in the array, giving us access to each individual item.

Open up the array-looping-methods-START.html file, which contains all the practice data we will be using for these exercises. Most of it is the same as the last video with the addition of a students array.

const toppings = ['Mushrooms', 'Tomatoes', 'Eggs', 'Chili', 'Lettuce', 'Avocado', 'Chilles', 'Bacon', 'Pickles', 'Onions', 'Cheese'];

If you wanted to loop out over every single one of the toppings in the array and log them to the console, or display them to the user, the very basic loop we have is the .forEach().

You should recognize it from previous exercises we did, when we were adding event listeners to multiple elements.

What we are going to do is take toppings and use the forEach method on it, passing it a callback function that will run once for each item in the array.

We can define our function outside or inline.

function logTopping(topping) {
  console.log(topping);
}

toppings.forEach(logTopping)

array forEach output in console

If you refresh the page, you will see that we are logging every single one of the toppings as we loop over them.

One thing Wes likes to do is throw a debugger into the foreach and take a look at the dev tools.

Modify the code as shown below to add the debugger breakpoint πŸ‘‡

function logTopping(topping) {
  console.log(topping);
  debugger;
}

When you refresh the HTML page, the debugger should open once it hits the first item in the array.

placing debugger in the logTopping callback function

As you can see, the debugger is in paused state. We have access to the call stack, and it tells us we are in the function logTopping.

Below that, the debugger tells us what the topping variable is equal to which is "Mushrooms", as well as the value of the this variable, which is equal to the Window.

paused status in debugger in the dialog box

If you click the symbol shown in the image above twice, the JavaScript code will continue running.

Now we are on the "Tomatoes" item. You can click all the way through the array.

As you know, we can also inline the function as shown below and it will still work exactly the same πŸ‘‡

toppings.forEach(topping => {
  console.log(topping);
})

One thing you might be having trouble with is where is this topping variable shown highlighted below is coming from. You may be wondering if it's a special keyword because it is a singular of toppings which is the name of the variable that holds the toppings array.

different ways to write forEach loop

If you remember back to when we learned about arguments and placeholders we said that arguments were the actual values and the parameters were the placeholders.

When we define the function, we put a placeholder, a parameter in there, and then when the forEach loop is called, JavaScript will slot the appropriate array item value into our parameter variable, whatever we may have called it.

To capture the argument, simply define the function with a parameter.

How do we know that?

We can look at the forEach() docs on MDN.

forEach mdn documentation for syntax

In our case, we chose to name the currentValue parameter topping.

We also have the ability to get the index and the array, so let's take a look at what that looks like.

Modify the code like so πŸ‘‡

function logTopping(topping, index, array) {
  console.log(topping, index, array);
}

toppings.forEach(logTopping);

When you refresh the HTML page and open the console, you will see that for each item in the array, the actual item was logged, the index and also the original array.

console log of the loop with current looping value, index and whole topping array

Why would you need to pass the original array?

Because if you need to grab something from the original array, you can.

Let's do a quick example where we have to loop over each topping and:

  • log the topping
  • log the next topping if there is one
  • log the previous topping if there is one
  • if it's the last item in the array, log "goodbye"

The first one is easy, simply add console.log(topping).

Let's do the next topping.

We have the index already and the original array, which we will rename because array is a bad parameter name. We also won't name it toppings because we already have a toppings array that lives outside of this function. Let's rename it to originalArray instead, like so πŸ‘‡

function logTopping(topping, index, originalArray)

Add a log of originalArray[index] and refresh the HTML page.

adding a log of originalArray[index] + 1 to access current looping value via index

console.log(originalArray[index + 1]);

So now if you try adding 1 to the index as shown above, you should get the next one. πŸ‘‡

Modify the code as shown below to add a log to see when it's looping

function logTopping(topping, index, originalArray) {
  console.log(topping);
  console.log(originalArray[index + 1]);
  console.log('--------πŸ•-----');
}

When you refresh the HTML page, you should see the following πŸ‘‡

accessing the current looping value directly or via array index in console

If you scroll all the way to the bottom, you will see that when we get to the last one, the next index returns undefined.

at the last index next element returns undefined

We can check whether the next topping exists or not by adding the following code πŸ‘‡

const nextTopping = originalArray[index + 1];

if (nextTopping) {
  console.log(nextTopping);
}

Now if you refresh the page and look at the console, you will see that for the last item, we are not logging the next one because it doesn't exist.

removing the undefined based on a ternary check whether we have a value at the next index or not

We can go a bit further and make it a bit easier to understand using a ternary function.

const nextTopping = originalArray[index + 1];
nextTopping ? console.log(nextTopping) : null;

That works just the same. Instead of putting null, you could put an empty string "", it doesn't matter as long as you put something there.

Now the previous topping.

Move the prevTopping and nextTopping variables to the top of the function and use the ternary operator to log the previous topping like so πŸ‘‡

const nextTopping = originalArray[index + 1];
const prevTopping = originalArray[index - 1];

prevTopping ? console.log(prevTopping) : null;
nextTopping ? console.log(nextTopping) : null;
console.log('--------πŸ•-----');

console log of the prevTopping and nextTopping by adding 1 in the index or subtracting 1 from it

Now the first and last topping should only have 2 items logged while all the other items have 3 items logged.

If it's the last item in the array we need to log "goodbye". How can we do that?

Let's use .length on the array and a ternary statement.

index === array.length - 1 ? console.log('Goodbye') : console.log("getting the next topping");

printing goodbye when we reach the end of array using length property of array

Let's break down what we did exactly in that last example.

Sometimes it helps to make it more readable if you put part on it's own line like so πŸ‘‡

index === originalArray.length - 1
  ? console.log("Goodbye")
  : console.log('Getting the next topping');

So the condition we are checking is index === originalArray.length - 1, which checks whether the current index matches the last index in the array.

We have access to the index of the currrent item in the index variable, and we can get the index of the last item in the array by doing originalArray.length - 1.

If it is the last index, log "goodbye" and if it doesn't, log "getting the next topping".

You could use an if statement instead of the ternary statement, it would work just as well.

We can also use the && hack we learned about earlier, like so πŸ‘‡

index === originalArray.length && console.log('Goodbye');

Why does that work?

Because if the first statement is true, it will keep going for the next one and if it is false, it will short circuit and never get to the second one.

That is what we referred to as abusing conditionals in our previous videos.

That wraps up the forEach method.

It is a bit different than the other looping methods because it doesn't return any values.

Notice how when we loop over each of our items we don't store our results in a variable like below πŸ‘‡

const result = toppings.forEach(logTopping);

When you loop over an array with forEach it doesn't actually return anything to you. It goes off and does some work for every item that is in that array.

Let's see how that is different from what Wes likes to call the 'Big Three' which are:

  • Map
  • Filter
  • Reduce

We will go over those in the next video.

Find an issue with this post? Think you could clarify, update or add something?

All my posts are available to edit on Github. Any fix, little or small, is appreciated!

Edit on Github

Syntax Podcast

Hold on β€” I'm grabbin' the last one.

Listen Now β†’
Syntax Podcast

@wesbos Instant Grams

Master Gatsby

Master Gatsby

Building modern websites is tough. Preloading, routing, compression, critical CSS, caching, scaling and bundlers all make for blazing fast websites, but extra development and tooling get in the way.

Gatsby is a React.js framework that does it all for you. This course will teach you how to build your websites and let Gatsby take care of all the Hard Stuffβ„’.

MasterGatsby.com
I post videos on and code on

Wes Bos Β© 1999 β€” 2021