If you've been writing JavaScript for even a short amount of time, you're probably still aware of how quickly the language is changing. Given all of these changes, that means there are also multiple ways to perform the same function. In this case I'm referring to looping over arrays using a for-each
construct.
So what's the best way to do it? That question depends on a few things, like what JS version you're using, if you can use instance methods, etc. In this article I'll be exploring a number of ways to loop over arrays in JS.
Array's forEach Method
A widely supported method (except for in IE 8, unsurprisingly) is the Array.prototype.forEach
method. It works by accepting a callback function with the parameters currentValue
, index
, and array
. In many cases, only the currentValue
and index
parameters are used.
Here is an example:
let items = ['one', 'two', 'three', 'four'];
items.forEach(function(val, idx) {
console.log(`${idx}: ${val}`);
});
// Output:
//
// 0: one
// 1: two
// 2: three
// 3: four
This is a great method due to its simplicity and clean syntax, although there are some downsides to it. Most notably, it's difficult to break out of this loop, unlike the built-in for
loop where you can use the break
keyword. With forEach
you must throw an exception in order to exit the loop early.
As the MDN documentation points out, if you need to break out of a forEach
loop, then this method is the wrong tool. In this case, some better options would be:
- Built-in
for
loop (detailed below) - Built-in
for-of
loop (detailed below) Array.prototype.every()
Array.prototype.some()
Array.prototype.find()
Array.prototype.findIndex()
The Array.prototype.*
methods above can exit their loops by returning a truthy value that tells the loop if it should continue on.
The forEach
method is good for when you have very simple looping requirements, and you don't need a lot of control over the actual looping behavior. However, this simplicity comes at a cost. It's about 95% slower than the built-in for
loop, but for most people this slowdown will be insignificant.
Built-in for Loop
The built-in for
loop (also known as a simple for
loop) is probably the most well-known of the options since it works the same way in JavaScript as in many other languages. The syntax is as follows:
let items = ['one', 'two', 'three', 'four'];
for (let i = 0; i < items.length; ++i) {
console.log(`${i}: ${items[i]}`);
}
// Output:
//
// 0: one
// 1: two
// 2: three
// 3: four
This kind of for
loop has a number of advantages:
- It's familiar to most programmers
- Control loop continuation
break
andcontinue
keywords - Control counter direction (via
++i
or--i
) and rate (i.e.i+2
) - Partial looping (i.e.
for (let i = 0; i < items.length/2; ++i)
)
With this much control over your loop, you also have to deal with its verbose syntax, which is why it's often avoided for simpler use-cases.
Note that the example shown above assumes you're using ES6 JavaScript, otherwise you'll need to declare the i
variable using var
and outside of the loop itself.
Built-in for-in Loop
Probably the most often misunderstood forms of looping in JavaScript is the for-in
loop. At first glance it seems like you can use this to loop through each index in an array, but it's actually meant to loop through the enumerable property names of an object, and not necessarily just indexes.
For example, here is how it's used with arrays:
let items = ['one', 'two', 'three', 'four'];
for (let i in items) {
console.log(`${i}: ${items[i]}`);
}
// Output:
//
// 0: one
// 1: two
// 2: three
// 3: four
And here is how it is meant to be used with objects:
let obj = {hi: 'bye', one: 'two', foo: 'bar'};
for (let o in obj) {
console.log(`${o}: ${obj[o]}`);
}
// Output
//
// hi: bye
// one: two
// foo: bar
Many developers will actually explicitly advise against using this for iterating over arrays, especially if the order is important since order is not guaranteed.
If you want to loop over an array with this style of syntax, then for-of
is recommended, which is the focus of the next section.
Built-in for-of Loop
The for-of
loops have a very similar syntax to for-in
, which we just saw. However, they main difference is that it iterates over iterable objects (like Strings, Arrays, Maps, Sets, etc.), whereas for-in
iterates over all non-Symbol, enumerable properties of an object.
In practice, here is what that looks like:
let items = ['one', 'two', 'three', 'four'];
for (let i of items) {
console.log(i);
}
// Output:
//
// one
// two
// three
// four
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
Notice that the i
variable is no longer the index, but instead it's the actual array value. And since it only works on iterables, we can no longer use an object:
let obj = {hi: 'bye', one: 'two', foo: 'bar'};
for (let o of obj) {
console.log(o);
}
// Output:
//
// TypeError: obj is not iterable
In terms of syntax and functionality, this is a bit of a compromise between the Array.forEach
function and built-in for
loop since the syntax is cleaner than the simple for
loop, and it still allows you to use loop "control" keywords like break
and continue
, unlike forEach
.
Another nice feature is that it works well with generators, so you can more easily take advantage of this in your loops:
function* myWords() {
yield 'foo';
yield 'bar';
yield 'baz';
}
for (let w of myWords()) {
console.log(w);
}
// Output:
//
// foo
// bar
// baz
Conclusion
As you can see, there are quite a few ways to perform a for-each loop over an array in JavaScript, and the construct you choose largely depends on what you want to accomplish and your specific use-case.
In this article we saw how to iterate over arrays using Array.forEach
, built-in for
loops, for-in
loops, and for-of
loops. Feel free to leave a comment below with any critiques or improvements that you see.