JavaScript - Lesson 3. Decisions, decisions!

Decisions, decisions!

Learning objectives:

The if statement

This is the simplest way in which we can get a JavaScript program to make decisions. In its simplest form, the if statement looks like this:

if (condition)
  { // Statements to be executed go here
    // Put in as many statements as you think fit
  }

The condition is a statement which may be true or may be false. If it is true, the statements inside the { } are executed. If the conditions is false, the statements aren't executed. Here's an example:

var userInput = prompt("Please enter a number","");
var actualNumber = parseFloat(userInput);
  // Remember, the previous statement turns the string into a number
if (actualNumber > 100)
  { document.write("You entered a really big number!");
  }

This short program gets the user to enter a number. If the number is bigger than 100 (actualNumber > 100), then the message is written on the screen. If the number isn't bigger than 100, then no message appears.

In fact, if the curly brackets after the condition only contain one statement, as they do in the example above (just the document.write statement), then you don't really need the curly brackets. I could have missed them out, and it would have had no effect on the program:

var userInput = prompt("Please enter a number","");
var actualNumber = parseFloat(userInput);
  // Remember, the previous statement turns the string into a number
if (actualNumber > 100)
   document.write("You entered a really big number!");

I have indented the document.write statement to indicate that it is controlled by the if statement, but this isn't really necessary. Remember, JavaScript is quite tolerant of the way that you lay out your statements on the screen, so both the statement could just as easily have been laid out as follows:

if (actualNumber > 100)
document.write("You entered a really big number!");

if (actualNumber > 100) document.write("You entered a really big number!");

It is useful to indent statements controlled by an if statement, as it gives a clear indication of the fact that they may be executed or they may not - depending on whether the condition succeeds or not - and it is a good habit to get into. Of course, you don't have to write messages on the screen:

if (a + b < 250)
  { var1 = a * b;
    var2 = "Too small";
  }

If the sum of a and b is less than 250, then two variables are set. The variable var1 is set to a*b (whatever value that is) and var2 is set to the string "Too small". If the condition fails, then these variables aren't set. You will notice that there is no need for an if statement to display anything on the screen using alert() or document.write(). Although I tend to include these a lot in my if statements, it is merely to demonstrate to the user whether the condition has succeeded or not.

You will see that I have put the curly brackets back in in that last example. This is because the if statement controlled two statements, not one, and the curly brackets were necessary to "glue them together".

Please note also: there is no semicolon at the end of the first line. Here I have duplicated the example and put in a semicolon:

if (a + b < 250);
  { var1 = a * b;
    var2 = "Too small";
  }

This is wrong, and the browser would complain bitterly!

Comparators

Symbols such as < and > are called comparators, because they compare two items. There are six of these altogether:

> bigger than >= bigger than/equal to == equal to
< less than <= less than/equal to != not equal to

Please note, if you want to test whether two things are equal to each other, use a double equals sign (==) rather than a single one (=). If you want to test whether two things are different (not equal), then put a ! sign in front of the equals (!=).

var userInput = prompt("Please enter any number except 6","");
var num = parseFloat(userInput);
if (num == 6)
  document.write("No, idiot! You entered 6.");

One of the most common errors (it has caught me many times) is putting a single equals sign in tests rather than double ones. JavaScript should spot these and point them out to you! The following, for example, is wrong:

if (num = 6)
   document.write("No, idiot! You entered 6.");

AND && and OR ||

You can join conditions together to form multiple ones. If you include the symbol && between two conditions, then the if statement only passes if both the individual conditions are true. For example:

if (a < 10 && a > 0)
  { // These statements are only executed if a is less than 10 and a
    // is bigger than 0 i.e. if a is between 0 and 10.
  }

if (friend1 == "Tony" && friend2 == "Jim" && friend3 == "Pete")
  { // These statements are only run if all the variables match
    // the values specified
  }

If any one of the conditions joined by && fails, then the whole of the joint condition fails.

Similarly, you can join the conditions with || which means that the condition will succeed if either one (or both) of the conditions passes. This is less fussy than && - as long as at least one of the conditions succeeds, then the entire condition will succeed:

if (val == 1 || val == 2.6 || val > 10)
   alert("You entered 1, 2.6 or any number bigger than 10");

Operator Precedence

Consider this line which has been extracted from an if statement:

if (a > 6 || b < 10 && c == 4)

Here we have three comparisons joined together, the first two with || (OR) and the second two with && (AND). The question is: When the browser works out the conditions, does it do the || first, or the && first?

The rule is, JavaScript always does the && first (unless there are brackets - more on this later!) This means that the browser works out b < 10 && c == 4 first. If b is less than 10 and c is 4, then this part of the condition is true. It then matches the result of this test with a > 6 using ||, i.e. if either a is larger than 6, or the result of the previous && part was true, then the whole test passes.

If this all seems rather complex, I have summarised the action of the if statement above in a table, showing whether each of the individual parts is/are true, the result of the entire if statement (i.e. does the entire condition inside the brackets succeed or fail?) and a comment where appropriate:

a > 6 b < 10 c == 4 Does the whole thing succeed? Comment
No No No No
No No Yes No
No Yes No No
No Yes Yes Yes
Yes No No Yes In these cases, the states of b and c don't matter, as a > 6 and that is enough to make the || part work!
Yes No Yes Yes
Yes Yes No Yes
Yes Yes Yes Yes

Although JavaScript normally does the && part first, you can make the || more important than the && part by putting it within brackets. The brackets should include the || itself, and the conditions on either side of it, as shown in the following example:

if ((a > 6 || b < 10) && c == 4)

You will notice that we now have a pair of round brackets within another pair of round brackets. This looks odd, but is grammatically correct. In this case, the (a > 6 || b < 10) part is worked out false, and then the result is matched with c == 4 using &&. Just look what difference it makes to the table of results:

a > 6 b < 10 c == 4 Does the whole thing succeed?
No No No No
No No Yes No
No Yes No No
No Yes Yes Yes
Yes No No No
Yes No Yes Yes
Yes Yes No No
Yes Yes Yes Yes

else

What you saw up above was the simple version of the if statement. You can also add an else clause as follows:

if (condition)
  { // Statements which are executed if the condition passes
  }
else
  { // Statements which are executed if the condition fails
  }

The statements which follow the else are only executed if the condition fails. In this way, at least one set of statements is carried out - either before the else or after it. Of course, there is no reason why you can't put one if statement inside another:

if (a == 6)
   document.write("The value of a is 6");
else
 { if (b > 10)
     document.write("b is larger than 10 and a is not 6");
 }

In this case, note the closing curly bracket, }, at the end of the statement. By tracing this bracket upwards, you should be able to see the opening curly bracket, {, that it matches. Needless to say, aligning the brackets carefully, as you see in the example above, is useful to ensure that all the brackets are matched correctly.

Below I have written the same example again, but this time the second if statement also has an else part:

if (a == 6)
    document.write("The value of a is 6");
else
  { if (b > 10)
      document.write("b is larger than 10 and a is not 6");
    else
      document.write("b is 10 or less, and a is not 6");
  }
Roads off in all directions!

The switch statement

The command switch is a variation on the if statement. Instead of having a condition which can be true and false (i.e. the decision can go one of two ways), the value of a variable is tested. The switch statement can then do one of several different things, depending on what the value of the variable is. Here is an example of a switch statement:

switch (myVariable)
 { case 1 :  a = 6;
             b += 2;
             document.write("I have altered a and b");
             break;
   case 4.6: p = a + 10;
             alert("Not a valid option");
             break;
   case -20: b = a - 2 * p;
             break;
   default:  alert("Unexpected value encountered.");
  }

In this case, the program tests the value of the variable myVariable. If myVariable has the value 1, then the block of statements after case 1: is carried out. When the program reaches the word break at the end of the block, it skips all the other cases and carries on after the switch statement.

Similarly, if myVariable has the value 4.6, then the block of statements after case 4.6: is carried out. Again, when the program reaches the work break, it jumps to the end of the switch statement (the curly bracket at the end) and carries on with the rest of the program.

The switch statement also specifies an action to be carried out if myVariable has the value -20.

The default part of the switch statement - which is optional - tells the program what to do if myVariable doesn\92t have any of the values specified. For instance, if myVariable had the value 6 or -100, then the default part of the switch statement would be executed. You will notice that the default part doesn\92t have a break after it. This is because, if the switch statement has a default part, then it is always the last item in the statement, so it doesn\92t need a break to jump to the end.

Please note the following about switch statements:

  • You can only test the value of a simple variable, not an expression. For that reason, a switch statement that started like this:

    switch (a)
     {  case 25 :   // etc.
    

    would be perfectly legal, but one that started off as follows:

    switch (a + b)
     {  case -40 :   // etc.
    

    would not be. This is because a + b is not a simple variable.

  • Unlike if statements, where the statements need to be blocked together using opening and closing curly brackets, { and }, the statements that form the parts of the switch statement don't need to be. The starting point for each block of statements is obvious - it is the word case followed by the appropriate value - and the stopping point of the block is equally obvious - it is the word break that instructs the program to skip over the rest of the switch statement.

  • Note which parts of the switch statement require a semicolon and which do not. Like the if statement, there is no semicolon after the variable being tested. The statements making up the cases have semicolons at the end as usual.

  • In fact, the word break is optional at the end of each block. However, if you don\92t include it, the program will not skip to the end when it reaches that point. Instead it will carry on with the statements for the next case! This may be what you want, of course, but please check to see whether you need to include break or not.

Here is another example of a switch statement. It comes from a program to check the amount of income tax a person is supposed to pay. People fall into one of three tax bands, and the tax is calculated from their income in one of three different ways:

switch (taxBand)
 { case 1 : tax_due = (income - taxAllowance) / 5;
            break;
   case 2 : if (income > 20000)
              tax_due = (income - taxAllowance - 20000) * 0.13;
            else
              tax_due = (income - taxAllowance) * 0.13;
            break;
   case 3 : tax_due = income * 0.11;
 }

You will notice that there is no default part to this switch statement (I did say it was optional!). That is fine, as long as you are sure that the variable taxBand will have one of the specified values. If it doesn't then the switch statement will do nothing, and execution will carry on with the statement after the switch. Since nothing comes after the case where the taxBand is 3, there is no need for a break at the end of this statement either.