JavaScript Lesson 4 - Loops

Round and round!

A loop is computer instruction which allows a program to repeat a sequence of statements more than once. There is a special computer term for this - we call it iteration. There are three types of loop in JavaScript, and each has its own specific uses: the while loop, the do-while loop and the for loop.

Each loop has a starting point in the program and an ending point, and includes either one statement or a whole block of statements. As you met before with the if statement, blocks of statements are enclosed within curly brackets, { like this }.

The ++ notation

Before we start talking about loops, I must mention a special notation that you will meet a lot in this section. You may see variables with ++ directly after them (with no intervening spaces). This simply means "increase the value of this variable by 1". Here is an example:

x = 2;
alert(x);   // This displays 2 on the screen
x++;        // Increase x by 1
alert(x);   // This displays 3 on the screen

The command x++ increased the value of x, in this case, from 2 to 3. You will notice that I did not use the keyword var in front of variable x when I first referred to it. This is because the statements that you see above have been taken from a larger program, and I am assuming that the variable x is declared properly previously using the var statement. Remember, with any variable, you only declare it using var once - after that you just use it without var.

This process of increasing a number by 1 can be done with any variable that holds a number (i.e. a whole number or a decimal number, positive, negative or zero), but it could not be done with a variable that contained a string. The following, for instance, would produce an error:

x = "I am a string";
x++;        // This should cause an error!

It is meaningless to "increase the value of a string by 1". There is a similar instruction called -- which decreases the value of a variable by 1 when it is placed directly after a variable name:

var long_variable_name = 20;
long_variable_name--;
y = long_variable_name + 10;

Here I have not put in any alert() statements, so that section of code would not produce any output on the screen. The variable long_variable_name starts off as 20, but is immediately reduced to 19 by the -- command. The value of the variable y is then set to 19 + 10, i.e. 29.

We can adapt the instruction so that it adds on or subtracts numbers other than 1. This is done by putting a plus (or minus) sign just before the equals sign in assignment:

first += 10;
second -= 23.4;

The first instruction here adds on 10 to the value of first, so that its value increases by 10. Similarly, the second instruction decreases the value of second by 23.4. Please note that there is no space between the + or - sign and the = sign. Note also the difference between the statements that you see above and the following code, which is almost identical.

first = 10;
second = 23.4;

Missing out the + or - sign directly before the = sign causes the variables to be set to those values, not increased or decreased by those values.

You can also multiply or divide a variable in a similar way by putting a * or / sign directly before the = sign. For example:

var temp_value = 1000;
temp_value /= 10;
alert(temp_value);  // This displays the value 100;
temp_value *= 4;
alert(temp_value);  // This displays the value 400;

You can also use the instruction %= to set a variable to the remainder when that same variable is divided by the following number. Perhaps an example will make that clearer:

var x = 79;
x %= 5;

In this case, when x is divided by 5, the remainder is 4, so x is set to the value 4.

The while loop

This loop specifies a condition at the start, and continues to iterate all the time that the condition remains true. The condition can be as complicated as you like, involving the use of && and || just as with if - else statements. The format of the while loop is as follows:

while (condition)
 {
   // Statements forming the body of the loop go here
 }

Take a look at this example:

<script language="JavaScript">
var x = 2;
while (x < 1000)
 { document.write(x + "<br />");
   x *= 2;
 }
document.write("The loop has terminated!");
</script>

The variable x is initialised to 2. When the loop is first encountered, the condition (Is x less than 1000?) is evaluated. It succeeds, so the loop is executed. The value of x is displayed, and then x is multiplied by 2. Then the condition is tried again, with x now equal to 4. This is still less than 1000, so the loop is executed again.

In fact, the loop carries on executing until the value of x is set to 1024. The condition then tests to see whether it is less than 1000 - it isn't, so the loop is not executed, and the program continues with the statement after the end of the loop, i.e. the program displays the message "The loop has terminated".

What you see on the screen is the following:

2
4
8
16
32
64
128
256
512
The loop has terminated!

Please note that the value of 1024 is not displayed on the screen. The reason is that the multiply statement sets the value of x to 1024 at the end of the loop, and the very next thing that happens is that x is tested to see if it is still less than 1000. Since the test fails, the document.write(x + "<br />") statement is never executed again.

It is perfectly possible for the loop never to execute at all. For instance, if the second line of the program above were changed to

var x = 1500;

Then no numbers are displayed on the screen. When the condition is tested for the first time, it fails (x is not less than 1000) and so the loop is never executed. The message about the loop having terminated is still displayed, of course, because that does not form part of the body of the loop.

The do-while loop

This loop is similar to the while loop, but with one subtle difference. This time, the condition is tested at the end of each iteration of the loop. This means that the loop must iterate at least once. It can never be skipped entirely. The format of the do-while loop is as follows:

do
 {
   // Statements forming the body of the loop go here
 }
while (condition);

Note that there is a semicolon after the bracket in the last line. In the following example, the user is asked to enter a number in the range 1 to 10, and the program won't accept any number which is out of this range:

do
 { var s = prompt("Please enter a number (1 to 10) : ","");
   num = parseInt(s);
 }
while (num < 1 || num > 10);

In this case the condition is that the number is out of range (less than 1 or greater than 10) as we want the loop to repeat and repeat until the number is in range. As soon as the user enters a suitable number, we want the loop to terminate.

In the case of the do-while loop, the curly brackets are necessary to enclose the statements. With the other sorts of loops, you can miss out the curly brackets if you only have one statement to include (just as you can with if statements), but with the do-while loop, they are necessary. The following:

do
 x += 2;
while (x < 2500);

Would be illegal. It would have to be written as

do
 { x += 2;
 }
while (x < 2500);

for loops

These are the hardest types of loop to learn, but probably the most powerful. They are normally used when you want a variable to count upwards or downwards, but they don't have to be by any means. The for loop contains a header enclosed within brackets. There are three parts to the header, separated by semicolons:

for (initialisation; continuing condition; end-of-loop statement)
 {
  // Statements making up the loop go here
 }

The initialisation part is a statement which is carried out before the loop is executed. It normally sets a variable to a certain starting value. The continuing condition is a condition tested at the start of each iteration. If the condition is true, then the loop iterates - and carries on repeating until the condition fails. The end-of-loop statement is an instruction that is carried out at the end of each iteration. This normally takes the form of the variable set up in the initialisation statement being increased or decreased. Typically a for loop might look like this:

for (count = 0; count < 20; count++)
 document.write("The value of count is " + count + "<br />");
document.write("After the loop, count is " + count);

This loop starts by setting the variable count to 0. The test is carried out: Is count less than 20? Yes it is, so the loop is executed. The document.write() statement is executed ("The value of count is 0"). The end-of-loop statement is carried out (count++) and the value of count goes up to 1. The whole thing is repeated, and the new value 1 is displayed.

In fact, the values 0 to 19 are displayed on separate lines. Notice that the value 20 is not displayed, because as soon as count is set to 20, the continuing condition fails (count is no longer less than 20) and so the loop is not executed.

One other point to notice here: There is only one document.write() statement inside the loop. This is because the there are no curly brackets in the loop. When a for loop contains no curly brackets, then the program assumes it only contains the single statement after the for header. The other document.write() statement in the example above is only executed after the loop has finished - it displays the final value of count, which, you won't be surprised to learn, has reached 20. Here is another loop with slightly more complex arithmetic:

var x, sum = 0, a = 100;
for (x = 20.5; 2 * x + 1 < 100 + x; a /= 2)
 { sum += x;
   x += a / 2;
 }
alert("Sum is " + sum);
Want to see this
demonstrated?
Magic hat

This loop is complicated, and I don't think anyone would write it quite like that, but it does illustrate a point. When the loop starts, x is set to 20.5. Before each iteration takes place, the condition is tested to see if twice x plus 1 is (still) less than 100 more than x. If it is, then the main body of the loop is carried out. You can probably see that the condition could be rewritten as (x < 99) with exactly the same results, but I am trying to demonstrate that conditions can be fairly complex here!

In this case the end-of-loop statement doesn't work on x directly, which is unusual. Instead, it works on a variable called a, and in the main body of the loop, the value of a is used to alter the value of x. This means that the continuing condition does eventually fail, and the statement after the end of the loop (the alert() statement) is executed. If you work through the loop on paper (or indeed run it as a program) you will find that it displays the value 186.5.

In this case, the curly brackets were necessary as there were two statements within the main body of the loop. It is quite easy to write a for loop that never ends, either accidentally or on purpose, as is the case with while or do-while loops. For instance, if one of the statements were removed from that example:

var x, sum = 0, a = 100;
for (x = 20.5; 2 * x + 1 < 100 + x; a /= 2)
 { sum += x;
 }
alert("Sum is " + sum);

(I have kept the curly brackets in, even though they are now no longer really necessary). In this case, although the value of a is changed at the end of each iteration of the loop, the value of x is never changed, and the terminating condition never fails. This loop would continue for ever - so beware!

Nested loops

It is perfectly possible to include one loop entirely within another. Such loops are known as nested loops. Here is an example, which displays all the times tables, from 1 x 1 = 1 to 12 x 12 = 144 on the screen:

var table, index;
for (table = 1; table <= 12; table++)
 { document.write("<p />"); // Blank line between tables
   for (index = 1; index <= 12; index++)
    document.write(index + " x " + table + " = "
                         + (index*table) + "<br />");
 }

This example shows a for loop nested within another for loop. Of course, there is no reason why the two different loops should be of the same variety. Here is the same example rewritten so that a for loop is nested inside a while loop:

var table = 1, index;
while (table <= 12)
 { document.write("<p />"); // Blank line between tables
   for (index = 1; index <= 12; index++)
    document.write(index + " x " + table + " = "
                         + (index * table) + "<br />");
   table++;
 }