The for loop
Introduction
Loops, also known as loop statements or iteration statements, are amongst those ideas in programming without which it's not just difficult but totally impossible to imagine this modern era of computing. Computers are the heart of automation and loops are the forerunner in enabling that.
Essentially a loop is merely a block of code together with some set of instructions on how long to keep that code running again and again. Back in the day when programming languages were invented, we didn't have the loops that we have today.
Over time as programming matured, people realized the need of such a neat programming construct that could fit in well with our intuitive reasoning of repetition. And thus came in the idea of loops as we use them today.
The two most conventional looping statements provided by almost all mainstream languages are for
and while
. Each has its own specific purpose but the idea is the same — keep repeating code until some condition becomes false
.
In this chapter, we start off by exploring all the nitty gritty details of the for
loop, followed by those of while
in the next chapter.
Let's begin.
What is for
meant for?
for
meant for?So what is for
meant for?
Well, precisely speaking:
The for
loop is meant to repeatedly execute a piece of code a known number of times.
For instance, if we want to print 'Hello'
a thousand times, or process as many <a>
elements in the HTML document as given by the variable anchorsLength
, then what we need is the for
loop.
In both of these cases, we know the limit to the iteration in one way or the other.
Compare this with, let's say, repeatedly asking the user to input a number (using a prompt()
dialog) until the input is -1
. Here clearly we don't know how many times would the code repeat before execution jumps out of it, hence this is not a situation meant for for
(however, technically, it could be used here as well — we'll shortly see how).
To restate it, for
is used to iterate a known number of times.
This is the reason why it's common to use for
to iterate over arrays using their length
property or, in general, any other sequence.
Anyways, with the purpose of for
understood, it's time to see how to write a basic for
loop.
Syntax of for
for
The for
statement begins with the for
keyword, followed by a set of configurations enclosed in a pair of parentheses (()
), known as the loop's header, followed by the statement to repeatedly execute, known as the loop's body.
Here's the syntax:
The pair of parentheses following the for
keyword consists of three different configurations, each separated by a semicolon (;
).
initialization
— here any variables to be used in the loop are initialized to given values. Moreover, even variables can be declared, for example usingvar
.condition
— the condition that's evaluated before every iteration. If it evaluates totrue
, the loop's body is executed, or else execution moves out of the loop.update
— an expression that's evaluated after every iteration. Typically this updates a variable's value that's used in the loop's condition so that it eventually becomesfalse
at a certain point, and thus the loop comes to an end.
Note that only expressions are allowed in each of these three sections. The only exception to this rule is in the first section where variable declarations can also be done.
Remember that a variable declaration is not an expression.
Moreover, it's invalid to include more or less than two semicolons in the for
loop's header. The individual expressions can be omitted but the semicolons have to be there. We'll see numerous examples of for
loops shortly below.
Now, if we were to go with all this description of the syntax of for
, we'd arrive at the following syntax.
Notice the [ ]
around each of the three configuration expressions — they signify the fact that all the three expressions are optional.
Simple examples
In this section, we aim to see a couple of examples of the usage of for
. With each example, we cover a lot of aspects of how to rewrite the for
loop.
Basic counting
Consider the problem of logging 0 to 4 using a for
loop.
This could very easily be done as follows:
0 1 2 3 4
Let's understand how this loop works:
First, in the statement
var i = 0
, we declare a new variablei
and initialize it to0
. This variable will keep track of the iteration we are currently on, and obviously also be used in the output. Such a variable that's meant to drive a given loop is often known as a loop variable, or even as a loop counter.Secondly, the condition
i < 5
means thati
should be less than5
for the given body to be executed.Lastly, the update expression
i++
means that after every iteration,i
is incremented by1
.
Hence, when i = 0
(initially), the loop executes; when i = 1
, the loop executes; when i = 2
the loop executes; this goes on until i
becomes equal to 5
at which point the evaluation of i < 5
yields false
and consequently the loop ends.
Simple, isn't this?
Note that the same output could've also been obtained by slightly modifying the condition. That is, instead of using i < 5
, we could've also used i <= 4
. This is because the condition i <= 4
(akin to i < 5
) yields true
for all the values 0
, 1
, 2
, 3
and 4
.
Here's an illustration of this fact:
0 1 2 3 4
Moving on, it's also not necessary to declare the variable in the loop's header — it could be declared before as well.
For example, the same code above could be expressed as follows:
Here, i
is declared in line 1 separately. Inside the for
loop's header in line 2, it's only assigned the value 0
to begin with.
The inline declaration of a loop variable inside the loop's header, as we did above, simply keeps the code compact and in certain cases (such as when we use let
) also affects the scope of the variable. Whenever possible, it's recommended to follow this convention.
Iterating over an array
One of the most common uses of for
is to iterate over an array, or any other sequence such as a string, or an HTML element collection (as we shall see in the HTML DOM unit).
The main thing used in this case is the length of the sequence (i.e. the total number of elements in it). For arrays, we already know that the length is given by the length
property.
Likewise, what we do is start at the index 0
and go as long as the index remains less than the length of the sequence. That's because the last element's index is one less than the length of the sequence, and therefore we don't have to end right at that very point.
In the code below, we have an array of numbers.
What we want to do is to log each number separately. That's accomplished as follows:
1 10 5 -9 -1
Once again, the loop's counter i
begins at 0
and goes right upto nums.length
(obviously excluding it), with being incremented after each iteration. Inside the loop's body, the i
th element of nums
is logged using nums[i]
.
Simply amazing!
If we want to, we can add a bit of spice in the code above. Instead of merely logging the current item of the array, we can also label it, and thus specify which index does the item have.
Consider the code below:
nums[0]: 1 nums[1]: 10 nums[2]: 5 nums[3]: -9 nums[4]: -1
As can be seen, this time the logs are a bit more detailed, covering the index of each logged item.
Alright, it's now time for one very quick and easy task...
Given the same nums
array as shown above, write some code to log its elements in reverse-order using a for
loop.
The expected output is the following:
-1 -9 5 10 1
Moving on, one common thing you'll notice across code snippets is the following:
Can you spot the difference? Well, it's the expression len = nums.length
and then the condition's modification to i < len
from i < nums.length
.
So what's so special about this change?
Recall that the loop's condition, i.e. the second expression after the semicolon (;
), is evaluated before every iteration. When the condition is i < nums.length
, the length
property is retrieved again and again and again in this evaluation.
The cost of this expression gets further increased if it is tied to an HTML element collection, in which case the whole computation of the collection is done again on the document's DOM tree. We'll see the details to this in the HTML DOM — Accessing Elements chapter.
To prevent this overhead of a property access (which, as stated before, might trigger an internal function call), programmers typically cache the value of the property in a variable and then refer to that variable.
Getting numbers input
Suppose we want to input some numbers to be added together. How many numbers we want to add is specified in an initial prompt dialog. Thereafter, as many additional prompts are made asking for each of the numbers to be added.
This is accomplished as follows:
Notice a couple of things here:
Firstly, the variable sum
is declared outside the loop, whereas i
is declared inside the loop's header. This can be a bit confusing for a newbie programmer as to where exactly to declare different variables. Fortunately, the key is very simple.
sum
is a variable meant to be used later on in the program, particularly when outputting the sum of the numbers. It's surely used in the for
loop, but it doesn't necessarily dictate the execution of the loop. In contrast, i
is the loop's counter which isn't meant to be used after the loop is done executing — it's purely limited to the loop.
Henceforth, this means that we should declare any variable that's meant to govern the execution of a loop inside the loop's header, and any other variable outside the loop.
Moreover, we begin at i = 0
even though we could've begun at i = 1
and changed i < n
to i <= n
. The thing is that it's very conventional and natural to begin at 0
and iterate the given number of times using the <
operator, even though sometimes the 0
might not have any practical significance as in the code above.
Note that if the expression (i + 1)
was repeatedly needed in the loop's body above, then we might've considered changing i = 0
to i = 1
and the conditional expression i < n
to i <= n
consequently as well to ultimately replace (i + 1)
with i
. However, the expression (i + 1)
was used only once and likewise we didn't consider modifying the loop's header.
Nested loops
A for
loop's body is a piece of code just like any other piece of code in a program. This means that it could contain another for
loop as well.
We usually refer to this as a nested loop. The inner loop is said to be nested inside the outer loop.
Nested loops are extremely common in programming. The majority of algorithms and data structures that you'll implement in your programming career will require you to employ nested loops. So let's quickly see how to set up a nested for
loop.
First let's come up with a scenario. Suppose we have to print ordered pairs of the form (
i
,
j
)
where i
is 0
, 1
, 2
and j
is 0
, 1
, 2
.
The way we'd do so is to first set i = 0
in the outerloop and then iterate with j
set to 0
, 1
and 2
; then increment i
and repeat the iteration over j
; then increment i
again and repeat the iteration over j
.
Consider the following code:
(0, 0) (0, 1) (0, 2) (1, 0) (1, 1) (1, 2) (2, 0) (2, 1) (2, 2)
It's very intuitive to follow along. For each iteration of the outer loop, the inner loop iterates three times.
Conventional naming: i
, j
and k
Note that using i
and j
as the loop counter variables in a nested loop is a convention. In fact, when there are a total of three loops, the variables used are i
, j
and k
in that order, starting with the outermost loop.
Perhaps this has been influenced from the theory of vectors and matrices in mathematics, where the same names are used to denote given variables.
Whenever designing nested loops in this course, we'll follow this convention unless there is a valid reason to use some other naming.
Time to test you understanding of nested loops.
Write some code to achieve the following output:
(0, 0) (1, 0) (2, 0) (0, 1) (1, 1) (2, 1) (0, 2) (1, 2) (2, 2)
The break
and continue
keywords
break
and continue
keywordsJavaScript, like almost all mainstream languages, provides two common control flow commands that dictate the execution of a loop — break
and continue
.
break
break
As the name suggests,
break
serves to break execution out of the loop that it is placed within
It's more or less like a shortcut to terminate a given loop. Anything following the break
command isn't executed in the loop — execution immediately jumps out.
Let's see a quick example.
In the code below, we have a basic loop, counting from 0
to 5
. The if
conditional inside the loop checks for i === 2
. The moment that happens, execution jumps out of the loop:
Here's the output produced by this code:
0 1
As is evident, the console.log(i)
statement executes just twice. In the third iteration, when i === 2
is true
, this leads to break
executing (on line 3). Consequently, the console.log(i)
statement (on line 5) gets ignored.
Let's try to modify the position where break
is called:
Here's the output produced by this code:
0 1 2
This time, since console.log(i)
is before the break
command, it executes for the third iteration as well (when i = 2
) unlike previously, and hence we get the third log.
break
only breaks execution out of the loop where it is used — it won't break execution out of the parent loop (if there's any).
break
is undoubtedly a useful command, but use it very carefully. It does reduce the readability of code. Whenever possible, try to avoid using break
in place of a simple and intuitive conditional expression in the header of the loop.
Let's see an instance of what does it actually mean for break
to reduce the readability of code.
Consider the following code:
1 11 3
The loop's header clearly shows that we want to iterate over the entire array. However, inside the loop, the additional if
conditional checks whether the current element is an even number. If it is, the loops exits.
In other words, we want to process the elements of the array until an even number is encountered.
As you may agree, this isn't immediately evident just by reading the loop's header. Ideally, we should try to be as informative in laying out the loop's condition as we can to make sure that anyone reading the code can pick up the purpose of the loop rightaway.
A much better approach would be to join both the given conditions together, as done below:
The loop's condition simply means that the execution of the loop should continue if i
is less than nums.length
(i.e. we don't exceed the last element of the array) and if nums[i]
is not an even number (i.e. we don't want to process an even number).
See how break
has been removed from our code, yet the loop still works as it did before.
The point of this example is to emphasize on the fact that break
should be used sparingly in loops. This isn't because it degrades performance — it doesn't affect the performance of the script in any way. It's only because it costs the fluid readability of the given code.
That's it.
continue
continue
Let's now move to continue
.
The continue
keyword serves to signal to the JavaScript to the engine to skip the current iteration and move to the next one.
Effectively this means that any code following the command isn't executed, and execution moves to the next iteration if there is any remaining. If no iteration is remaining, then obviously the loop terminates.
Let's consider a quick example.
In the code below, we iterate over the given array nums
and skip the loop's body if the current element is an even number.
1 11 3 5
Clearly, this code could be improved by removing the call to continue and instead using an if
conditional to check if a log ought to be made (i.e. the current number is odd).
This is accomplished as follows:
1 11 3 5
Without any doubt, this second code snippet is much more readable than the previous one that employed continue
.
Long story short: continue
, as with break
, is a very useful command to control the execution of a given loop. However, we should make sure to use it sparingly as well, just like break
, and rather try to use if...else
conditionals in a way that gets the same job done but in a more readable manner.
With this done, it's time to see the return
keyword as used inside a loop.
The return
keyword
return
keywordAs we saw in the chapter JavaScript Functions, the return
keyword is used inside a function to immediately terminate execution and return a given value to the calling context.
We also know that it's invalid to use return
outside a function. Therefore, if we want to use return
inside a loop, the loop has to be part of a function's body.
Using return
in a loop, which is obviously itself a part of function, is a very common idea. Why?
Simply because it does two things:
It breaks execution out of the function which effectively means that no matter how many loops are nested together,
return
would exit them all and the containing function as well.It returns a value to the calling context i.e. the place where the function was called.
One quick example could be a function that searches for a given number in a matrix (represented as an array of arrays).
The search would use a double nested loop and inside the inner loop a mere conditional to check for the number. If it finds the number we were searching for, true
is immediately returned before bringing the entire execution of the function to a halt.
Following is this example brought to the glyphs of code:
true true false
And this is it.
Last updated