For f@%#’s sake, should I use ‘for…of’ or ‘for…in’?

A guide to help you Google for loops less

There are certain things that always come up regularly in web development that I just can’t seem to cement into memory — splice() vs. slice(), css transition syntax, arguments and proper return values in reduce() vs. map() vs. filter() vs. sort(), to name just a few…

Those may crowd my Google history, but none come close to the basic for loop and its few, relatively simple variations.

I can’t be the only one, so let’s lay em’ all out, one-by-one, in the hopes of not having to wonder which is which every friggin’ time.

At the end of this post, I’ll provide a concise, bullet-point list of each variation and in what types of situations they make the most sense.

First things first — the basic for loop

This is the for loop variation we all know and love. It’s a common default option for any sort of iteration over an array, with plenty of flexibility in terms of where to start the loop, where to end, and how to move on from one iteration to the next.

This type of for loop uses the index position of the array to keep track of where we are in the iteration. So, we use the index to access the actual data at that position in the array.

const players = ['Alex', 'Becky', 'Charlie', 'Dylan'];
for(let index=0; index < players.length; index++){
console.log(`Player at index ${index} is ${players[index]}`)
}
//====Console Output====//
Player at index 0 is Alex
Player at index 1 is Becky
Player at index 2 is Charlie
Player at index 3 is Dylan

Awesome — easy to remember how and when to use this one.

If…

  • in doubt about what type of for loop to use on an array
  • you want to iterate over only a portion of the array, or skip over indexes
  • you want to iterate backwards, i.e. start at the end of the array and decrement the index as you go through the loop
  • you don’t learn anything from the rest of this blog post

forEach

As the name suggests, this array method does not provide the flexibility of the basic for loop — ya gotta handle each and every item in the array via a callback function passed to the method.

The callback function takes three arguments.

  • currentValue — current element in the array
  • index — the index of the current element in the array, just like the index in the basic for loop
  • array — the array that the forEach statement is being applied to / is a method of

With forEach(), we have two ways of outputting the players as we did with the basic for loop example.

One is a contrived, ugly way of outputting all of the players using forEach(), which is virtually identical to how we used the for loop, only here forEach() assumes the starting index is zero and that we’ll iterate through all of players.length.

const players = ['Alex', 'Becky', 'Charlie', 'Dylan'];
players.forEach(function(player, index, array){
console.log(`Player at index ${index} is ${array[index]}`)
})
//====Console Output====//
Player at index 0 is Alex
Player at index 1 is Becky
Player at index 2 is Charlie
Player at index 3 is Dylan

Doing it this way, though, doesn’t take advantage of the brevity and efficiency offered by the forEach method. It’s much cleaner and easier to use it like in the example below assuming we have no need for the index, just the element as is often the case.

const players = ['Alex', 'Becky', 'Charlie', 'Dylan'];
players.forEach(player => {
console.log(`Player's name is ${player}`)
})
//====Console Output====//
Player's name is Alex
Player's name is Becky
Player's name is Charlie
Player's name is Dylan

Oh, another super useful version of the forEach() method exists on NodeLists, which are kind of like arrays of DOM elements returned by common DOM methods like querySelectorAll().

So, you probably want to use a forEach() array method when…

  • you want to iterate over every element in an array, and have no need to break the loop prematurely
  • you have no need for the index of the array element being processed
  • map(), reduce(), filter() or some other built-in array method doesn’t suit your needs
  • iterating over NodeLists and working with the DOM in general

For…in

Who else has tried to use this on an array, only to be confused by what pops out? Anyone? Bueller?

const players = ['Alex', 'Becky', 'Charlie', 'Dylan'];
for(let player in players){
console.log(`Player is ${player}`)
}
//====Console Output====//
Player is 0
Player is 1
Player is 2
Player is 3
WHAT?! I WANTED THE PLAYER NAME, NOT THE INDEX!!

It works on arrays, but only provides the index of the current item, similar to the basic for loop. And while this method of iterating over an array is valid, it’s not particularly unique or useful.

From the MDN docs…

Because the order of iteration is implementation-dependent, iterating over an array may not visit elements in a consistent order. Therefore it is better to use a for loop with a numeric index (or Array.prototype.forEach() or the for...of loop) when iterating over arrays where the order of access is important.

The for…in loop is meant to be used on an object, iterating over the keys of that object.

Let’s try the same for…in loop we just used on the players array, but instead make a team object with our players.

const team = {
seeker: 'Alex',
chaser: 'Becky',
beater: 'Charlie',
keeper: 'Dylan'
}
for(let player in team){
console.log(`${team[player]} is a ${player}`)
}
//====Console Output====//
Alex is a seeker
Becky is a chaser
Charlie is a beater
Dylan is a keeper

So, when do you want to use the for…in loop?

When…

  • you want to iterate over an object, particularly the keys of that object
  • iterating over an array, where the basic for loop is less optimal than using for…in loop to get the current index of the array items

For…of

This gift from ES6 is insanely flexible and applicable, allowing you to iterate over damn near everything, with a unique operation/output for each type of iterable object, e.g. Array, String, function arguments, Nodelist, and less common or newer object types like Map, Set, and Symbol.

How is it different from the for…in loop? From the MDN docs…

Both for...in and for...of statements iterate over something. The main difference between them is in what they iterate over.
The for...in statement iterates over the enumerable properties of an object, in original insertion order.
The for...of statement iterates over data that iterable object defines to be iterated over.

Using our previous players array, we can see how for…of could replace the need for the forEach or basic for loops.

const players = ['Alex', 'Becky', 'Charlie', 'Dylan'];
for(let player of players){
console.log(player)
}
//====Console Output====//
Alex
Becky
Charlie
Dylan

You may want to use the for…of loop when…

  • iterating over pretty much anything iterable — so not Objects!
  • trying to incorporate new, more modern JavaScript in your code

A quick reference of everything in this post

Use a basic for loop when…

  • in doubt about what type of for loop to use on an array
  • you want to iterate over only a portion of the array, or skip over indexes
  • you want to iterate backwards, i.e. start at the end of the array and decrement the index as you go through the loop

Use the forEach method when…

  • you want to iterate over every element in an array, and have no need to break the loop prematurely
  • you have no need for the index of the array element being processed (though still accessible using callback function parameters)
  • map(), reduce(), filter() or some other built-in array method doesn’t suit your needs
  • iterating over NodeLists and working with the DOM in general

Use a for…in loop when…

  • you want to iterate over an object, particularly the keys of that object
  • iterating over an array, where the basic for loop is less optimal than using for…in loop to get the current index of the array items

Use a for…of loop when…

  • iterating over pretty much anything iterable — so not Objects!
  • trying to incorporate new, more modern JavaScript in your code

Examples

for loop

const players = ['Alex', 'Becky', 'Charlie', 'Dylan'];
for(let index=0; index < players.length; index++){
console.log(`Player at index ${index} is ${players[index]}`)
}
//====Console Output====//
Player at index 0 is Alex
Player at index 1 is Becky
Player at index 2 is Charlie
Player at index 3 is Dylan

forEach

const players = ['Alex', 'Becky', 'Charlie', 'Dylan'];
players.forEach(player => {
console.log(`Player's name is ${player}`)
})
//====Console Output====//
Player's name is Alex
Player's name is Becky
Player's name is Charlie
Player's name is Dylan

for…in

const team = {
seeker: 'Alex',
chaser: 'Becky',
beater: 'Charlie',
keeper: 'Dylan'
}
for(let player in team){
console.log(`${team[player]} is a ${player}`)
}
//====Console Output====//
Alex is a seeker
Becky is a chaser
Charlie is a beater
Dylan is a keeper

for…of

const players = ['Alex', 'Becky', 'Charlie', 'Dylan'];
for(let player of players){
console.log(player)
}
//====Console Output====//
Alex
Becky
Charlie
Dylan

If you liked this post, please subscribe and follow me @ryanjyost!

Want to better understand DOM Events?

http://www.domevents.info/