Why do JavaScript Developers Hate FOR Loops?

I mean, who doesn’t, right?Photo by Dmitry Vechorko on UnsplashC-style FOR loops are old, verbose to write and require you to also define an extra variable and keep track of it throughout the whole thing.With so many alternatives available, why would t…

I mean, who doesn’t, right?

Photo by Dmitry Vechorko on Unsplash

C-style FOR loops are old, verbose to write and require you to also define an extra variable and keep track of it throughout the whole thing.

With so many alternatives available, why would the language even support it still? Why isn’t there a proposal to remove the FOR loop?

The fact is, dear FOR-loop-hater, that every construct in our favorite language has a place, and a reason to be there. Yes, including the FOR loop. So let’s take a look at what alternatives are there, their particular use cases and let’s also analyze why the traditional FOR loop is still valid.

Shall we?

What alternatives are there?

Since JavaScript loves us so much and wants us to be happy and filled with options, there are two (or three, depending on how you look at them) different ways for us to repeat the same piece of logic multiple times (other than the one you hate, of course).

Note from Author: Do note that I had to re-write the above paragraph multiple times, since I wanted the language to be as generic as possible. We’ll see why in a minute.

That said, when we think about ways to write a FOR loop that don’t involve the version we all love to hate, we come up with answers like the following.

The .forEach method of arrays

Yes, this is likely the most popular version because as JS developers we all love functional programming. Right?

We like to think of ourselves as lords of code and look down upon other loops in disgust when we use the .forEach method.

In case you’re not super familiar with it (in which case: how dare you!), this method allows you to call a function for every element inside an array. Said function will receive each element as its first argument, and your logic can use it for whatever you need.

Something like this:

Now, this is a perfectly good way of dealing with elements inside an array. However, this method — and all array methods to be honest — has one major “issue” if your logic is asynchronous: it can’t deal with it.

Let’s take another look at the above example, but let’s pretend we’re using an external service for the printing out into the console:

The result of that execution is the following:

Notice how the last line printed in the code, is actually the first one to be written into the console. We’re not getting the behavior we wanted, and that is simply because the forEach method will not await for its internal function to be finished on every iteration. And since this is a closed method, we can’t really change the way it works without re-writing it completely.

Yes, there are alternatives that deal with lists of promises, but we’re talking about FOR loops here, so let’s move on.

Another teensy tiny detail about this method is that it’s an Array method, meaning that we can’t really use it to iterate over the properties of an object for example. Not unless we first get the list of properties, like with Object.getOwnPropertyNames or similar, but that would be cheating. So let’s see what we can do about this as well.

The for..on and for..in loops

OK, so these two are very similar and can be considered as living somewhere in between the one we all hate and the forEach loop. Why? Because they provide a lower level abstraction than their functional counterpart, but not as low level as the one-who-shall-not-be-named.

Let’s take a look at both of them:

Can you spot the difference between them? It’s easy actually, the for..in iterates over the indexes of the array, and that is what it’ll assign to our local variable i . On the other hand, the for..of variation deals with the actual values inside the array.

So when picking which one, you have to remember what exactly you want to work with. If you need the indexes, use the first one, if on the other hand, you need the values directly use the second one.

“But Fernando”, I hear you say, “are they async-compatible?”. Good question dear for-loop-hater, good question. Let’s see:

As you can see, I’m using the same logic as before. What do you think the result would be here?

YES! We get the expected behavior now. And that should not come as a surprise, after all we’re dealing with a very basic construct here that allows us to define exactly what happens between iterations. So the await key works as one would expect (there is no hidden “magic” working around it as before).

Let’s also quickly test what would happen if we tried to use these loops with objects instead of arrays:

OMG, they also work with objects!! That means these already are more powerful and versatile than the .forEach method. That is wonderful. We got everything we were asking for, so why would we keep going from here?

Well, there are two main “issues” I haven’t highlighted yet with these 2 solutions:

  1. We’re always iterating over the entire array/object. We can’t really loop through the last 10 elements for example. Not unless we make a copy of the original array with fewer values, that is.
  2. We’ve always been dealing with arrays (or objects in the last example). But what if we have a piece of logic that needs to be executed multiple times, but does not depend on a list of elements? Do we still have to create a fake list just so we can use a loop? That doesn’t seem right, does it?

As I mentioned before, when I defined the FOR loop, the language had to be generic for this exact reason. I didn’t want to spoil the whole point of the low-level FOR loop: the flexibility to do whatever you want, however you want it.

Let’s take a look at it.

If you liked what you’ve read so far, consider subscribing to my FREE newsletter “The rambling of an old developer” and get regular advice about the IT industry directly in your inbox.

The FOR loop to the rescue

The syntax for this bad boy is the following:

That is how powerful the FOR loop is, as you can see, it’s just a loop that will run until a condition is met. That’s all.

  • The <VARIABLE INIT> section is usually used to initialize the internal counter. But you can also either leave it empty or initialize more variables at the same time. There are no limitations. The point of this section is that it gets executed at the start of the loop and never again.
  • The <END CONDITION> is a boolean expression that tells the loop when to stop. This condition will be checked at the start of every iteration. If you leave it empty, the loop will run forever. And as with any boolean expression in JS, you can make it as complex or as simple as you want.
  • The <CODE TO EXECUTE EVERY ITERATION> is usually reserved for the change in the value of the counter variable that is checked on the <END CONDITION> section. However, this is just code that gets called by the loop itself without us having any control over it. You can put anything you like here.

The usual form this loop takes is the following:

And yes, that is a valid use, but why limit yourself?

Look at those 3 very valid and also beautiful FOR loops. The first two are quite straightforward. Following the definition from above, you can pretty much understand their behavior.

But what about the last one? What would you say is the output of that loop?

It’s going to start i at 0 but x at 19, and on every iteration is going to increment i but it’s also going to decrement x until neither i is lower than 10 NOR x is higher than 5.

Have you guessed it yet? Here I’ll give you a hand:

Yes, it’s not what everyone expects. But look at it this way. By the time i reaches 10, x is still over 5, so the loop keeps going. Once x reaches 4 the loop ends, because by then i is already 14. And since the checks are done at the start of every loop, we can’t really see those last two numbers printed.

This level of flexibility is what makes this FOR loop so great, and at the same time, it’s what makes it so hated. The abuse it has received over the years has prompted developers to come up with higher-level abstractions of it for specific use cases.

However, just because you COULD abuse this wonderful tool if you wanted to, there is nothing forcing you to.

When would you use this version of the loop?

“To each their own”

Ever heard that phrase before? That is the very definition of what you need to do when trying to pick the right version of the FOR loop.

If you’re dealing with a list of elements inside an array, you’re most likely set with the forEach method (or any of its functional variations).

If on the other hand you’re looking to iterate over an object, or perhaps you’re looking to execute some asynchronous functions on every iteration. Consider the for..of and for..in variations — or maybe look into promises a bit more.

But if you’re looking to iterate over a random section of a list, or perhaps you need the freedom to define a very complicated logic around your loop, the lower-level version of all of them is going to give you the power you need.

Just remember the words of uncle Ben:

With great flexibility, comes the responsibility of not writing obscure code that is not commented anywhere.

Or something like that, I’m paraphrasing him at this point but you get the idea. If you’re making it complex, make sure you document it somewhere.

Use the right tool for the right problem, there is a reason why the other abstractions were created, don’t hate on them either.

At this point I hope I’ve convinced you to stop hating the lower level tools and especially, the poor old FOR loop, who’s been with us since the beginning of JavaScript.

But in all seriousness, every feature of the language has a purpose, whether that purpose falls within your daily routine is a whole different matter. Instead, try to avoid spreading hatred towards a construct that perhaps — just perhaps — you don’t fully understand.

Build composable web applications

Don’t build web monoliths. Use Bit to create and compose decoupled software components — in your favourite frameworks like React or Node. Build scalable and modular applications with a powerful and enjoyable dev experience.

Bring your team to Bit Cloud to host and collaborate on components together, and speed up, scale, and standardize development as a team. Try composable frontends with a Design System or Micro Frontends, or explore the composable backend with serverside components.

Give it a try →

Learn more


Why do JavaScript Developers Hate FOR Loops? was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


Print Share Comment Cite Upload Translate
APA
Fernando Doglio | Sciencx (2024-03-28T12:02:39+00:00) » Why do JavaScript Developers Hate FOR Loops?. Retrieved from https://www.scien.cx/2022/04/20/why-do-javascript-developers-hate-for-loops/.
MLA
" » Why do JavaScript Developers Hate FOR Loops?." Fernando Doglio | Sciencx - Wednesday April 20, 2022, https://www.scien.cx/2022/04/20/why-do-javascript-developers-hate-for-loops/
HARVARD
Fernando Doglio | Sciencx Wednesday April 20, 2022 » Why do JavaScript Developers Hate FOR Loops?., viewed 2024-03-28T12:02:39+00:00,<https://www.scien.cx/2022/04/20/why-do-javascript-developers-hate-for-loops/>
VANCOUVER
Fernando Doglio | Sciencx - » Why do JavaScript Developers Hate FOR Loops?. [Internet]. [Accessed 2024-03-28T12:02:39+00:00]. Available from: https://www.scien.cx/2022/04/20/why-do-javascript-developers-hate-for-loops/
CHICAGO
" » Why do JavaScript Developers Hate FOR Loops?." Fernando Doglio | Sciencx - Accessed 2024-03-28T12:02:39+00:00. https://www.scien.cx/2022/04/20/why-do-javascript-developers-hate-for-loops/
IEEE
" » Why do JavaScript Developers Hate FOR Loops?." Fernando Doglio | Sciencx [Online]. Available: https://www.scien.cx/2022/04/20/why-do-javascript-developers-hate-for-loops/. [Accessed: 2024-03-28T12:02:39+00:00]
rf:citation
» Why do JavaScript Developers Hate FOR Loops? | Fernando Doglio | Sciencx | https://www.scien.cx/2022/04/20/why-do-javascript-developers-hate-for-loops/ | 2024-03-28T12:02:39+00:00
https://github.com/addpipe/simple-recorderjs-demo