Battle of the JavaScript for loops (for, for…in, for…of, forEach, etc.)
Tags: javascript, webdev, programming
Published: 2022-03-09 12:22:03

Iterating over objects and arrays is something every developer has to do. Whether you’re a beginner or a seasoned veteran, eventually you’re going to have to find something in a larger data set. But when iterating (looping) through something, you might find yourself a little lost with all of the options available to you. So here’s a quick breakdown of the main ones.

**Note:** This isn’t a beginner's introduction to how `for` loops work, but rather a comparison of the `for` loop options available.

# for (the classic)

`for` is by far the most common loop. It isn’t specific to arrays or objects (or to any data structure in fact), and can be combined with almost anything to create powerful and fast loops, so long as you configure them properly. Here’s a classic `for` loop in action:

{% embed https://gist.github.com/DuncanMcArdle/61ebf91e107c33678f1b65e8596ef74c %}

`for` loops can be used in conjunction with `break`, `continue` or `return` to create some seriously versatile functionality.

# forEach

`forEach` allows you to return an entire entry from an array. It’s simple and straightforward, but doesn’t come with the additional `break`, `continue` and `return` functionality found with a classic `for` loop. It does however, look incredibly clean.

{% embed https://gist.github.com/DuncanMcArdle/196bd99b0587f26182e99139d32dd3c5 %}

Think of a `forEach` loop as being like a cleaner, array-specific `for` loop.

# for...in

The `for...in` loop allows you to loop through the enumerable **properties** of an object, including those set by the parent prototype (if one is present).

{% embed https://gist.github.com/DuncanMcArdle/148009f1b4e4b3cd32d4aa759a66b287 %}

Now unfortunately, that’s probably not what you want. You could put a check in on each iteration to see if the property belongs to the object or its prototype (`hasOwnProperty` would be perfect here), but that really damages readability. In addition, `for...in` loops only return strings, so if you’re looping through an array (which does, despite the mention of properties above, work), you probably don’t want to use one of these.

# for...of

`for…of` iterates over any enumerable object, won’t convert the values it finds, and does so whilst supporting the functionality of `break`, `continue` and `return`.

{% embed https://gist.github.com/DuncanMcArdle/6ae77f517b04a61619b1ef716a676a2a %}

Think of `for...of` as being like a cleaner version of the `for` loop, specifically for iterable objects, without losing any of the `for` loop’s functionality.

# The Object class

One consistent downside of the above `for` loops is that their compatibility with objects vary. That all changes however, with the use of the `Object` class.

By using `Object`, we can convert our objects to arrays (I promise that’ll make sense shortly), and then loop through those arrays with all of the above loops.

Now, you’ll commonly see `forEach` used in conjunction with this method, but the problem with that is that you lose the ability to `break`, `continue` or `return` during the loop. For that reason, I’d recommend considering a classic `for` loop in conjunction with this method, but here’s an example of both for completeness (note that this example uses `Object.keys()`, which is covered below):

{% embed https://gist.github.com/DuncanMcArdle/052598439b5b817f4bf3fc0389dac6f9 %}

## Object.keys()

This handy function returns an array of keys found in the specified object. Even more handily, it only includes keys belonging to the immediate object, and not its prototype, so that means no more seeing the parent props like we do with `for...in`.

{% embed https://gist.github.com/DuncanMcArdle/7c1ced6073f4286a18763da3956dd55a %}

## Object.entries()

This one returns each and every entry in its entirety, including both the property and value. This can be more helpful if you want to retain the key that you’re seeing the value of (which you often do).

{% embed https://gist.github.com/DuncanMcArdle/a40d8a1bb080ae892658fc230caa4861 %}

## Object.values()

As the name suggests, this method returns only the values found in an object. No index, no key, just values.

{% embed https://gist.github.com/DuncanMcArdle/39534bb83961191f88410fd8abed9399 %}

# Wrapping things up

You might have reached this point and be hoping for me to say “So make sure kids, that you always use the _best_ loop, the `<insert loop here>`”.

But c’mon, that’s rarely how programming works.

In reality, the right approach for you depends entirely on the context. Some of the above methods are faster than others, some are more useful, others are more readable. It’s up to you to find the right combination of the above, but hopefully this has helped you on your way to making that decision.