The Secrets Surrounding For Loops In JavaScript

Unravel the secrets that remain hidden from the majority of Developers

Somnath Singh
Jan 8 · 12 min read
Image for post
Image for post
Photo by Christina @ wocintechchat.com on Unsplash

You will occasionally want a group of statements to get executed more than once. We accomplish this task using loops. In most programming languages, the majority of code execution time is spent within loops. Looping over a series of values is one of the most frequently used patterns in programming and as such is also one of the areas where efforts to improve performance must be focused. Understanding the performance impact of loops in JavaScript is especially important, as infinite or long-running loops severely impact the overall user experience.

There are four loop types provided by JavaScript. In this article, we will focus on for loop. But whatever we will learn here can also be applied to other kinds of loops. The for loop is ideal for situations in which you want to execute a group of statements a specific number of times. The nature of arrays requires that we be able to loop through or iterate on the values of that array.

The for statement simplifies loops that follow a common pattern. Most loops have a counter variable of some kind. This variable is initialized before the loop starts and is tested before each iteration of the loop. Finally, the counter variable is incremented or otherwise updated at the end of the loop body, just before the variable is tested again. In this kind of loop, the initialization, the test, and the update are the three crucial manipulations of a loop variable. The for statement encodes each of these three manipulations as an expression and makes those expressions an explicit part of the loop syntax:

Image for post
Image for post
for loop syntax in JavaScript

The codes defined inside the parentheses are vital they control the start and end of the for loop. In total, we put three statements in the parentheses and separate them using two semicolons.

  • The first statement is called the initial expression.
    We use it to initialize one or more loop counters. This statement is executed at the beginning of the for loop and is only executed once!
  • The second statement controls when the for loop should stop.
    It will be executed before every loop. The for loop will stop when the second statement returns a falsie value. The second statement must be set correctly otherwise you may get an infinite loop.
  • The last statement is what we use to update each loop.
    It gets executed at the end of each loop.
Image for post
Image for post
Codes defined inside the curly brackets will be repeatedly executed.

This is all that we learn about for loops in most places.
While in most places they never go beyond this, in this article we will explore the unknown side of the for loop. This will not only give you a deeper understanding of for loop but also make you a better developer.

Are you ready? Lets us start!

The first statement can be defined outside the for loop.

Image for post
Image for post
initialization defined outside the for loop
Image for post
Image for post
The output of the above code

The last statement can also be moved into the curly brackets

Image for post
Image for post
post-loop-expression or increment gets defined into the curly brackets
Image for post
Image for post
The output of the above code

To enable a for loop to work normally. Just make sure the second statement is set correctly and the two Semicolons are capped.
Well, It wasn’t that contrasting! was it? But what if I say that we can merge the second and third statements.🙀 So, how do we do that?

First we declare a counter and set its initial value to negative 1.

Image for post
Image for post
Pay attention here it is negative 1, not 0

In the second statement, We compare the last element index with counter++ we can get the last element index by subtracting 1 from the array length. There is no need to set the post-loop-expression or increment.

Image for post
Image for post
Pay attention to the conditional test here.

You may be wondering how on earth this program can work?

Image for post
Image for post
The second statement can be tested to either true or false

Here, the second statement will be tested and executed before each loop. So every time a new loop has started the value of the counter variable will go up by 1. This is why we set counters’ initial value to negative 1.
During the first loop, the counter value in the curly brackets will become 1.
Eventually, the counter value will be bigger than the index of the last element. The comparison will return false and shut down the for loop.

Image for post
Image for post

Let us test it with the body statement

Image for post
Image for post
Image for post
Image for post
We can see the result is the same as before.

There is another way to merge the second and third statements.

Image for post
Image for post
First, we declare a counter and set its value to zero.
Image for post
Image for post
Then we declare another variable and name it item.

We will use the item variable to store an array element in the second statement.

Image for post
Image for post
We set the value for the item variable.

We retrieve elements using counter++ as the index.

Image for post
Image for post
There is no need to set the third statement.

So, how can this program work?

The second statement gets executed before each loop.

The code will first retrieve an array element using the counter as the index and assign the retrieved element to the variable item, then the value of the counter will go up by 1.

Pay attention here value of the counter won’t change until the array element has been retrieved and assigned. This is because the increment operator is placed behind the counter , not before it. It means using the variable’s original value first and adding one to it later. So the counter’s value won’t change in the current line. This is also why we set the counter’s initial value to zero not a negative one, in the first loop counter's value is still zero.

It won’t become 1 until the second loop the counter value will go up by 1 with each loop eventually its value will be bigger than the index of the last element. If we retrieve an element using an index that does not exist in the array we will get undefined, undefined is a false value, as a result, the for statement will come to a stop inside the curly brackets.

Image for post
Image for post
Visualisation of the above code

We can directly output the item variable, we can see every element has been output.

Image for post
Image for post

But there is a problem with this program. All element values must be truthful. If there is a false value, the for loop will end immediately depending on your program design.

Image for post
Image for post
We added null as a second element in the array
Image for post
Image for post
The loop ends immediately after it found a null value in the array.

This feature can either save or cause you trouble!

Are you tired? Shall we go backward also?
I promise you will learn something profound about the performance of using loops in your code, which you won’t discover anywhere else!
Just have some patience, we are uncovering the secret life of loops.

First, we create a variable and we name it counter, and set its value to array length.

Image for post
Image for post
There is no need to subtract one from the array length.

Then we create a for loop. The first statement has already been set but you still need to keep the semicolon.

Any idea of how to set the second statement?

Image for post
Image for post
what should we replace ?? with?

We connect the counter to the decrement operator and compare it with zero.

Image for post
Image for post
We require the counter to be bigger than zero

Inside the curly brackets, we retrieve the array element using counter as the index value

Image for post
Image for post

Let us put all the pieces together.

Image for post
Image for post
Image for post
Image for post
We can see all elements have been retrieved

In the above code, the array was iterated backward every time a new loop starts.

The counter value will be compared with zero and then drop by 1 with every loop. The value of the counter will drop by 1. Eventually the counter value will drop to zero as a result. The comparison expression will return a falsie value which will shut down the for loop.

Image for post
Image for post

Again wondering how on earth the above code worked?

In the above program, the key is the decrement operator!
It is placed behind the variable counter, if the counter value is 1 in the parenthesis then in the curly brackets its value will drop by 1 and become 0. This is why we set counters’ initial value to array length, not array length minus 1.

Let’s try the second method.

First, we declare two variables. The first one is named counter and we set its value to array length -1

Image for post
Image for post
We name the second variable item.
Image for post
Image for post
we retrieve the array element using counter- - and assign it to item
Image for post
Image for post
in the curly brackets, we output variable item
Image for post
Image for post
we can see the program works

Every element that has been output in the array was iterated backward.
The initial value of the counter is the index of the last element. The second statement will retrieve the element using the current counter and assign the element value to the variable item then the value of counter will drop by 1.

The key part is still the decrement operator being placed behind the counter . The value of counter will drop by 1 in the next loop. Eventually, the counter value will become negative 1 which is an illegal index value using an illegal index value will give us undefined, which is a false value, as a result, the for loop will stop.

Image for post
Image for post
For better Visualisation

The key of the two programs is if you put the increment or decrement operator behind a variable, the variable value will not change until the next line. In the current line, the variable value stays unchanged.

Phew! That was quite long, wasn’t it?

If you still here then I have something for you!
If you have gone through all the examples carefully, then by now your brain must have grown a bit and you must be seeing the loops differently.

Loop Performance 🔥

Which loop to use is constant source of debate. Of the four loop types provided by JavaScript, only one of them is significantly slower than the others: the for-in loop. Since each iteration through the loop results in a property lookup either on the instance or on a prototype, the for-in loop has considerably more overhead per iteration and is, therefore, slower than the other loops.

Aside from the for-in loop, all other loop types have equivalent performance characteristics such that it’s not useful to try to determine which is fastest. The choice of loop type should be based on your requirements rather than performance concerns. If loop type doesn’t contribute to loop performance, then what does?

There are just two factors:

  • Work done per iteration
  • Number of iterations

By decreasing either or both of these, you can positively impact the overall performance of the loop.

Decreasing the work per iteration

It stands to reason that if a single pass through a loop takes a long time to execute, then multiple passes through the loop will take even longer. Limiting the number of expensive operations done in the loop body is a good way to speed up the entire loop.

Image for post
Image for post

The above examples do a property lookup for arr.length every time through the loop. Doing so is wasteful, as this value won’t change during the execution of the loop and is therefore an unnecessary performance hit. You can improve the loop performance easily by doing the property lookup once, storing the value in a local variable, and then using that variable in the control condition:

Image for post
Image for post

You can also increase the performance of loops by reversing their order. Frequently, the order in which array items are processed is irrelevant to the task, and so starting at the last item and processing toward the first item is an acceptable alternative. Reversing loop order is a common performance optimization in programming languages but generally isn’t very well understood.
Both were kept in mind when we altered the usual way of writing a for loop in the initial examples. So, if you paid attention to those examples, then Congratulations! You can now write performant loops.

Decreasing the number of iterations

When iterated thousands of times, even the fastest code in a loop body will add up. Additionally, there is a small amount of performance overhead associated with executing a loop body, which just adds to the overall execution time. One can lead to greater performance gains by decreasing the number of iterations throughout the loop. The most well-known approach to limiting loop iterations is a pattern called Duff’s Device.

Invented by programmer Tom Duff while he was at Lucasfilm Ltd. in 1983. Duff’s Device is a technique of unrolling loop bodies so that each iteration does the job of many iterations. We should thank Jeff Greenberg, as he was the one who first published Duff’s Device code in JavaScript in the year 2001 (original implementation was in C). The JavaScript implementation looks like this:

Image for post
Image for post
Here doSomething() is an operation that you want to execute more than once

The basic idea behind this Duff’s Device implementation is that each trip through the loop is allowed a maximum of eight calls to doSomething(). The number of iterations through the loop is determined by dividing the total number of items by eight. Because of Algorithms and Flow Control, not all numbers are evenly divisible by eight, the startAt variable holds the remainder and indicates how many calls to doSomething() will occur in the first trip through the loop. If there were 12 items, then the first trip through the loop would call process() 4 times, and then the second trip would call process() 8 times, for a total of two trips through the loop instead of 12.

Whether or not it’s worthwhile to use Duff’s Device, depends largely on the number of iterations you’re already doing. In cases where the loop iterations are less than 1,000, you’re likely to see only an insignificant amount of performance improvement over using a regular loop construct. As the number of iterations increases past 1,000, however, the efficacy of Duff’s Device increases significantly. At 500,000 iterations, for instance, the execution time is up to 70% less than a regular loop.

A summary of what we have learned

  • There are four loop types provided by JavaScript.
  • The first statement(initialize) can be defined outside the for loop.
  • The last statement(increment) can also be moved into the curly brackets
  • We can merge the second and third statements
  • If there is a false value in the test, the for loop, it will end immediately.
  • for-in loop is slowest of all due to property lookup.
  • Work done per iteration and Number of iterations determines the performance of any loop.
  • Duff’s Device history and its practical implementation in JavaScript.
  • Using Duff’s Device in larger iterations, the execution time is up to 70% less than a regular loop

We are not finished yet!

If you want to solidify what you learned here, then open repl.it, and try out the codes shown in the article. Measure the performance, and tell me in the comments which one you found the most performant.

Liked the post? I would appreciate it if you share it with your friends! Want some more insightful articles? Well, then catch me on Twitter! 🐥

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store