Course: JavaScript

Progress (0%)

JavaScript Control Flow

Chapter 9 46 mins

Learning outcomes:

  1. What is control flow
  2. The if and else conditionals
  3. The switch conditional
  4. The for loop
  5. The while loop

Introduction

Perhaps, one of the most paramount aspects of modern-day programming is that of control flow. This chapter is devoted briefly exploring the different kinds of control flow constructs in JavaScript.

But before that, let's quickly understand what's meant by the term 'control flow'.

The term 'control flow' basically refers to the flow of control, i.e. the flow of execution, in a computer program. First, the control is in one part of the code, then it moves to another one, and then to another one, then possibly back to the previous one, and so on.

This literal flow of control is powered by control flow constructs (statements) in programming languages. These constructs are typically divided into two categories:

  1. Conditional, sometimes also referred to as selection constructs. These constructs execute code based on the evaluation of given conditions.
  2. Iterative, sometimes also referred to as looping constructs. These constructs execute code repetitively, again based on the evaluation of given conditions.

The most common conditional statements are if and else while the most common iterative statements are for and while. These are provided by many many programming languages.

In the following sections, we'll go over the following five control flow statements in JavaScript: if, else, switch, for and while.

The if statement

Conditional statements occur in almost all programming languages that we use today. They are simply statements that evaluate a certain condition and then execute code based on the outcome of that evaluation. JavaScript is no way behind. It supports conditonal statements out of the box.

In the last chapter on JavaScript Data Types, we came across Boolean values, i.e true and false. Conditional statements are the biggest application of Booleans.

In this section, we shall see one of the most common conditional statements in JavaScript and programming, in general — the if statement.

The if statement executes code if a given condition is true.

Here's the syntax of an if statement:

if (expression) statement;

We start with the if keyword, followed by a pair of parentheses (()). Inside these parentheses, we put an expression that is the condition to evaluate. If this condition evaluates to the Boolean value true, the following statement is executed.

statement here is called the body of if (just like we learnt about the body of a function), while the part if (expression) is called the header of if.

The if statement evaluates the given expression and checks to see if it reduces down to true. If it does, it means that the condition of the statement is met and, likewise, its body must be executed.

However, if the opposite happens, i.e. the given expression evaluates down to false, this means that the condition isn't met and hence the statement at the end of the if statement must not be executed.

Let's consider a simple example.

Below we create a Boolean variable isRaining specifying whether it's currently raining outside or not:

var isRaining = true;

For now, we put a dummy value inside this variable — true.

However in a real world application, such as an app notifying the user of the weather and climatic conditions of a given location, this Boolean variable would be given a value very meaningfully, like by retrieving and parsing actual data from a satellite.

Anyways, with the Boolean in place, next we set up a simple if statement to alert the user that he/she should go out with an umbrella if it is raining:

var isRaining = true;

if (isRaining) alert("Don't forget an umbrella!");

Notice how natural this code sounds. It says that 'if it is raining, alert the user to not forget an umbrella'.

As soon as we execute this code, we get an alert made. This is because the given expression isRaining evaluates down to true.

Live Example

So this was easy. What do you say?

One thing worthwhile mentioning over here is that, as per the syntactic rules of JavaScript, it's not required to put the body of if on the same line as the header.

For instance, we could write the code above like this without having any effect on its semantics (i.e. meaning):

var isRaining = true;

if (isRaining)
   alert("Don't forget an umbrella!");

The new line and additonal indentation here is really handy — it helps us distinguish the if statement's header from its body. In fact, more than just handy, it's a convention, used even in other programming languages with a similar C-like syntax as JavaScript.

For some languages, such as Python, the indentation is not just a convention, but a part of the syntax, i.e. it's a must!

But an even more mainstream convention for JavaScript (and other C-like languages) is to encapsulate the body inside a pair of curly braces ({}) as follows:

var isRaining = true;

if (isRaining) {
   alert("Don't forget an umbrella!");
}

As we'll learn later on in this unit, besides a couple of other things, a pair of curly braces ({}) represents a block statement in JavaScript.

A block statement is simply a single statement that's comprised of multiple statements.

It can be thought of a group for a sequence of statements.

So in the code above, the body of if happens to be a block statement which contains just one statement, that is the call to alert().

By virtue of its readability and flexibility to be able to execute more than one statement, we'll stick to using a block statement as the body of if and of almost all similar statements throughout the rest of this chapter and the rest of this course.

Coming back to if, let's consider another example.

This time instead of using a Boolean value directly inside the if's header, as we used isRaining above, we'll use a relational operation expression.

What is a relational operation?

A relational operation determines the relationship between given values and resolves down to a Boolean to imply that relationship. A relational operator carries out a relational operation.

You might already be familiar with relational operators from your early school math classes. Recall the inequality symbols ::\lt::, ::\leq::, ::\gt:: and ::\geq::?

These are all examples of relational operators.

In JavaScript, for instance, these inequality symbols are denoted as < (less-than), <= (less-than-equal-to), > (greater-than) and >= (greater-than-equal-to), respectively.

Notice how the <= and >= operators both have the equals sign (=) in the end. This is extremely important to make sure — placing the sign at the start, as in =< and =>, is invalid and will lead to errors, most probably.

In addition to these four operators, we also have the identity operator, denoted as ===, to check whether two values are identical to one another.

Let's now consider a couple of examples of using these operators:

10 < 50
true
10 < 10
false
10 < 9
false
10 > 10
false
10 > 9
true
10 >= 10
true
10 <= 10
true
10 === 10
true
10 === 9
false

We'll discover more relational operators in JavaScript in one of the upcoming chapters, JavaScript Operations.

Here's the idea: we'll ask the user to enter a number greater than 10. If the input value is not greater than 10, i.e. the requirement is not met, then we'll simply make an alert stating that the given input is invalid.

The code below demonstrates this:

var num = Number(prompt('Enter a number greater than 10'));

if (num <= 10) {
   alert('Invalid input');
}

If you're good at maths, you'll be able to realize that checking whether a number is not greater than 10 is the same as checking whether the number is less than or equal to 10. The latter is how we perform our check, i.e. using the <= (less-than-equal-to) operator

Live Example

Later on in this page, once we discover the while loop, we'll extend this code to keep repeating the input prompt as long as the entered value is not valid.

As we shall see later on in the JavaScript Conditionals chapter, and even in general throughout this course, tons and tons of important ideas in the word of computing rely on the if statement. It's totally impossible to imagine modern-day computing without if!

But, if doesn't stand alone to claim this position. There is a similar statement that works together with if in laying out complex conditions in a given piece of code.

That statement is called else.

Let's explore it...

The else statement

The else statement is another conditional statement in JavaScript.

Unlike if, it couldn't be specified alone — there has to be an if statement preceding an else.

So what's else used for?

The else statement executes a piece of code if the condition in the preceding if statement isn't met.

In other words, if the condition mentioned in an if statement evaluates down to false, the corresponding else block takes over.

Together, the if and else statements are generally referred to as the if...else statements.

The syntax of else is pretty much similar to if — just remove the condition as it's not required:

if (expression) statement;
else statement;

Alright, let's consider an example using else.

We'll bring our rainy day example back and extend it to show two alerts — one when it is raining and one when it is not raining. In addition, we'll also change the dummy value of isRaining to false (previously it was true) so that we could test the else clause.

Here's the code:

var isRaining = false;

if (isRaining) {
   alert("Don't forget an umbrella!");
}
else {
   alert("No need for an umbrella.");
}

Live Example

The moment we run the code, we get the second alert, just as we expected.

Also notice the body of else. Just like that of if, it's a block statement (denoted using {}) as well and happens to be comprised of just one statement.

Over to the second example, again the same one we considered in the section above on if.

Previously, if the user entered a number not greater than 10, we made an alert specifying that the entered value is invalid. This time, we'll handle the valid case as well, by alerting the number if it is indeed greater than 10:

var num = Number(prompt('Enter a number greater than 10'));

if (num <= 10) {
   alert('Invalid input');
}
else {
   alert(num);
}

Live Example

Perfect!

Note that it's invalid to put an else statement without a preceding if statement.

Even logically, this sounds weird. We're used to sentences like 'if this, then that, or else that', not to sentences like 'else that' where the 'else' seems to appear out of nowhere.

Shown below is an invalid piece of code:

var num = Number(prompt('Enter a number greater than 10'));

else {
   document.write(num);
}

The error here is caused due to the else statement, which has no preceding if.

Henceforth, always make sure that each and every else that you use has a preceding if.

The switch statement

Apart from the if...else statements, there is another conditional statement in JavaScript called switch.

The switch statement is useful when we have multiple outcomes depending on the final value of a given expression.

The switch statement literally switches over given blocks of code depending on whether a given case is matched.

The syntax of switch is much different from that of if and else:

switch (expression) {
   case match1:
      statements;
      break;
   case match1:
      statements;
      break;
   ...
   case matchN:
      statements;
}

We start with the switch keyword, followed by a pair of parentheses (()), followed by the case block of the switch statement.

The case block defines various cases to match expression against and even the code to execute, i.e. statements, when either of them gives a match.

Each case begins with the case keyword, followed by a value to match against expression, followed by a colon (:), followed by the case's corresponding set of statements. If this value matches expression, the corresponding block of code following the colon (:) is executed.

The break keyword, at the end of each cases's corresponding block of code, serves to break execution out of the switch statement once that block of code gets executed. It's redundant to give it in the last case since after executing the last case, execution moves out of the switch statement anyways.

We'll see the details to break in the section below.

Let's consider a very basic example to clarify this complex syntax.

Suppose we want to create a program where the user is asked to enter a three-digit number representing an HTTP response status code, and then gets back the corresponding status message returned.

Obviously, as there are many HTTP status codes, we won't be considering all of them right now — just the following ones:

  • 200 which means OK.
  • 302 which means Found.
  • 404 which means Not Found.
  • 500 which means Internal Server Error.

In the code below, we accomplish this idea with the help of switch:

var code = Number(prompt('Enter an HTTP response code:'));
var msg;

switch (code) {
   case 200:
      msg = 'OK';
      break;
   case 302:
      msg = 'Found';
      break;
   case 404:
      msg = 'Not Found';
      break;
   case 500:
      msg = 'Internal Server Error';
}

document.write(code + ' ' + msg);

Live Example

With this code, if the user enters an HTTP status code that isn't amongst the four values given above, i.e. 200, 302, 404 and 500, then msg would remain undefined and be printed literally as 'undefined' out on the document.

How can we deal with such a case and instead, print 'Unknown'?

Well, we could define a default case for this, using the default keyword. The default case of a switch statement gets executed when none of the preceding cases matches.

Here's how to use default with switch:

switch (expression) {
   case match1:
      statements;
      break;
   case match1:
      statements;
      break;
   ...
   case matchN:
      statements;
      break;
   default:
      statements;
}

The default case begins with the default keyword (not with the case keyword), followed by a colon (:), followed by the case's corresponding block of code.

Writing default at the end of a switch statement is just a convention — not a syntactic requirement.

Alright, with default understood, it's now time to use it in the code above.

Recalling the problem, we needed to output a message saying 'Unknown when the input status code isn't amongst the values 200, 302, 404, and 500.

In the code below, we handle the rest of the cases besides these five codes with the help of default:

var code = Number(prompt('Enter an HTTP response code:'));
var msg;

switch (code) {
   case 200:
      msg = 'OK';
      break;
   case 302:
      msg = 'Found';
      break;
   case 404:
      msg = 'Not Found';
      break;
   case 500:
      msg = 'Internal Server Error';
      break;
default:
msg = 'Unknown'; } document.write(code + ' ' + msg);

Live Example

One thing worth mentioning here is that break isn't a part of the syntax of a switch statement. If we want to, we can skip putting a break at the end of every case's corresponding set of statements. However, this might change the outcome of the switch statement completely.

The way the switch statement behaves is what mandates us to use break inside cases so as to prevent execution from tipping over into the next case, when a preceding case gets matched.

By default, when a switch case gets matched, execution obviously starts from its corresponding set of statements, but then when execution completes and if there is no break, it enters into the next case, and then to the next one, and so on and so forth.

This is not a design error per se, but a desirable thing in certain scenarios when we want multiple cases to give the exact same outcome. We'll see the exact details of this in the chapter JavaScript Conditions — The switch Statement.

For now, you should stick to using break at the end of the set of statements of every, but the last, case of a switch statement.

The for loop

Conditional statements, as we saw above, are handy for many practical-level use cases. Modern-day computing clearly can't be thought without them. But conditional statements aren't the only paramount idea in the world of programming.

There exists another such idea, and an equally important one, which we call iteration, or looping. Iteration simply means to execute a piece of code over and over again, repeatedly.

Iteration sits right at the heart of computer automation. We define a piece of code and some condition on which it should stop, and then the computer takes on from there, continuously executing that code again and again, and again.

Nearly all modern languages provide utilities for iteration. JavaScript, in particular, defines two iteration statements: for and while.

In this section, we'll go over the former.

The for keyword, generally referred to as the for loop, defines a statement that is executed repeatedly as long as a condition holds.

The for statement is used to repeatedly execute code a known number of times.

It consists of three steps: variable declaration and initialization, followed by a condition to continue executing the loop, followed by an expression modifying the variables mentioned in the first step.

So what are these three steps for? Well, they just simplify writing code when we need to iterate a given number of times using for.

Here's the syntax of for:

for (initialization; condition; modification) statement;

initialization, condition and modification correspond to the three steps of defining a for loop, as stated above:

  • initialization defines variable declarations and assignments.
  • condition is an expression that must evaluate to true in order to execute statement.
  • modification is an expression evaluated at the end of each iteration.

Akin to if and else, statement is referred to as the body of for.

Let's try to print the text 'Hello World!' out on the document 5 times, using the for loop:

for (var i = 0; i < 5; i = i + 1) {
   document.write('Hello World!<br>');
}

Let's make intuition of the header of the loop here:

  • We begin by declaring a variable i and initializing it to 0.
  • Next up, we write i < 5 to say that the next iteration should execute if i is less than 5. This expression evaluates to true exactly 5 times (when i is 0, 1, 2, 3 and 4), thus executing the loop's body exactly 5 times.
  • Finally, we write i = i + 1 to say that i must be incremented by 1 at the end of each iteration.
  • As a whole, the statement document.write() gets executed 5 times.

    Live Example

    Easy!

    It's time to understand certain aspects of such for loops in more detail.

    The variable i in the code above is typically called a counter variable, or simply a counter. This is because it's literally used to count for the for loop.

    Moving on, the name i is a pretty conventional name for a counter variable. If you want to, you can surely call it a, c, counter, or anything you like, but using the i convention will be a lot more helpful.

    The third modification expression above was given as i = i + 1. This surely works. That is, i = i + 1 increments i by 1 at the end of each iteration, ultimately pushing the loop closer and closer to completion. However, it's a lot to type.

    JavaScript (and other C-like languages) realizes this and provides a much simpler expression to accomplish the same behavior as i = i + 1. It's called the postfix increment operator.

    The postfix increment (++) operator

    The postfix increment operator is denoted as ++, two plus signs (+) right next to each other, and serves to simply increment a given variable by 1.

    The postfix increment operator comes immediately after a given variable that we need to increment and does (almost) the exact same thing as manually adding 1 to the variable and then assigning the result back to the variable.

    For instance, to increment the variable i we saw above, we'd write i++.

    The usage of the postfix increment operator is extremely common in for loops. From now on, whenever we'll want to increment the counter of a for loop by 1, we'll use i++.

    Apart from this, notice the initialization of i to 0 in the loop.

    Is it necessary to initialize the counter to 0? Absolutely no.

    Then why do we use it? That's a good question.

    Why is the counter typically initialized to 0 in for?

    Technically, there's nothing that mandates us to initialize the counter variable of a for loop to 0. We could start on any number we like, as long as we make sure that it aligns with the loop's condition.

    For instance, below we rewrite the code above by initializing i to 1 and then obviously update the corresponding condition:

    for (var i = 1; i <= 5; i++) {
       document.write('Hello World!<br>');
    }

    If we run this code, we still get 5 lines of output, but the loop now begins with i = 1, not with i = 0, and the condition is now a less-than-equal-to relation (i <= 5) instead of a less-than relation (i < 5).

    Alright. But that ain't a problem, right? Absolutely not. That ain't a problem.

    So then what's the point of starting at 0?

    Well, starting at 0 is really handy, and sensible, when we process arrays using for. As you may recall, arrays begin at index 0 and so if want to iterate over an array using for, accessing each of its elements, we'd surely find it helpful to begin the loop's counter at 0.

    The structure of the for loop we saw above is so common that we could generalize it as follows:

    for (var counter = 0; counter < n; counter++) {
       statements
    }
    • In the loop's header, we declare and initialize a variable counter to 0 (remember that you'll need to name this variable to something else in your code).
    • Next, we write an expression counter < n to get the loop to execute n number of times (replace this as well).
    • We end the loop's header with counter++ to increment the variable counter.
    • Finally comes the loop's body

    Perfect!

    Let's see one more example.

    This time instead of outputting static content to the document, we'll generate it on-the-go in the loop's body using the counter variable i.

    The general form of each message will be 'This is iteration <i>' where <i> will be replaced by the number of that message ('1' for the first message, '2' for the second one, and so on).

    Here's the code:

    for (var i = 0; i < 5; i++) {
       document.write('This is iteration ' + (i + 1) + '<br>');
    }
    This is iteration 1
    This is iteration 2
    This is iteration 3
    This is iteration 4
    This is iteration 5

    The grouping of the expression i + 1, i.e. (i + 1), here is vital for the correct output of the program. It makes sure that first i + 1 is evaluated and then the rest of the expression.

    If we don't group it, here's what'll happen:

    for (var i = 0; i < 5; i++) {
       document.write('This is iteration ' + i + 1 + '<br>');
    }
    This is iteration 01
    This is iteration 11
    This is iteration 21
    This is iteration 31
    This is iteration 41

    Let's make sense of this weird input.

    Suppose that we're in the first iteration and so i = 0. Here's how the expression 'This is iteration ' + i + 1 + '<br>' will then be resolved:

    • First the expression 'This is iteration' + i gets evaluated. This performs string concatenation because one of the values involved in the operation is a string. In the end, we get the string 'This is iteration0'.
    • Next, the expression 'This is iteration0' + 1 gets evaluated. This again performs string concatenation and then yields back the string 'This is iteration01'.
    • Finally, the expression 'This is iteration01' + '<br>' gets evaluated. This is simple — the result is 'This is iteration01<br>'.

    So in the first iteration, document.write() gets the string 'This is iteration01<br>' to output.

    You could apply this same reasoning for subsequent iterations of the loop and, therefore, be able to reason how exactly removing the grouping of i + 1 leads to the wrong output.

    Simple?

    Let's consider yet another example.

    Besides iterating for a literal number of times, the for loop is used to iterate over sequences, such as strings and arrays, as well.

    In this regard, the length property of the sequence determines the value of n in the loop's header, while the counter variable, begining at 0, gets used as the index to access each item in the sequence.

    In the code below, we define an array nums and log each of its items one-by-one using the for loop:

    var nums = [1, 3, 5];
    
    for (var i = 0; i < nums.length; i++) {
       console.log(nums[i]);
    }
    1
    3
    5

    See how initializing i to 0 allows us to directly use i to access each element of the array. That is, we don't have to process i before it could be used to access an element.

    Let's try another example.

    This time, we'll make two console logs for each item in an array lang containing the names of some programming languages:

    var langs = ['C', 'C++', 'Python', 'Java', 'JavaScript'];
    
    for (var i = 0; i < langs.length; i++) {
       console.log('Language #' + (i + 1) + ':');
       console.log(langs[i]);
       console.log('\n') // blank line
    }
    Language #1:
    C

    Language #2:
    C++

    Language #3:
    Python

    Language #4:
    Java

    Language #5:
    JavaScript

    We'll cover for in detail in the JavaScript for Loop chapter.

The while loop

The second looping control structure provided by JavaScript is while.

The while keyword, also known as the while loop, denotes a statement that is repeatedly executed until some condition becomes false.

Syntactically, it's quite different from for:

while (condition) statement;

We start with the while keyword, followed by a pair of parentheses (()) where we specify the condition that must evaluate to true in order for statement to be executed, followed by the loop's body.

Akin to for, condition is checked before each new iteration.

At the core level, both for and while continue iterating only if the given condition is met i.e. it evaluates down to true. However, both are used for different purposes.

Difference between for and while

for, as we know, is more commonly seen when iteration is to be done on a given number of times, or over a sequence such as a string, or an array.

In contrary to this, while is usually used when iteration is to be done an unknown number of times where a counter variable isn't required to keep track of the iteration.

An example of using while would be to continue asking the user to enter a value in a prompt dialog until the entered value meets the desired criteria.

Below we set up a program that asks the user to input a programming language he/she knows in an input prompt. If the prompt dialog is canceled or given no value, we make an alert stating that the entered value is invalid and then display a prompt again. This goes on until the entered value is appropriate.

var lang = prompt('Enter a programming language:');

while (!lang) {
   alert('Invalid input.');
   lang = prompt('Enter a programming language:');
}

document.write('You know ' + lang + '.');

Live Example

The expression !lang returns true if lang is falsey i.e has a value that coerces into the Boolean false. This happens if it is an empty string ('') or the value null.

In both these cases, the body of while gets executed and consequently displays an input prompt again.

When the correct input is given, !lang returns false, execution jumps out of the loop (if it was inside the loop), and finally the input value is written out to the document.

"I created Codeguage to save you from falling into the same learning conundrums that I fell into."

— Bilal Adnan, Founder of Codeguage