Chapter 4. Making Decisions

Programming is much more than variables, functions, and calculations. If programming were as simple as those three things, computers wouldn't be anything more than giant calculators, and chances are good you wouldn't be reading this book.

What sets computers apart from other electronic calculation devices is their capability to simulate intelligence. Granted, it's the programmer who tells the computer how to behave and how and when to make decisions, but it's the computer that decides what action to take based on a set of criteria.

Making decisions is an important part of programming. At the core of decision making are conditions, and the program makes a decision based on whether or not a particular condition is met. There are a few control structures that use conditions to determine how code executes, but first let's look at how to write conditional statements.

CONDITIONAL STATEMENTS

In JavaScript, a conditional statement consists of an operation comparing two or more values to result in a Boolean value together with statements that may run, depending on the result. Recall from Lesson 2 that Boolean values consist of either true or false. A condition is said to have been met if the conditional statement results in true; otherwise, a value of false defines the condition as unmet. In order to get a true or false value, you typically use JavaScript's comparison operators.

Comparison Operators

Lesson 2 introduced several operators: the assignment operator to give a variable a value, the string concatenation operator to join two or more strings together, the typeof operator to determine a variable's data type, and mathematical operators to perform arithmetic operations. Similarly, JavaScript provides many operators to test conditions. These operators are binary operators, meaning they have a left side (the left operand) and a right side (the right operand). A comparison operator looks at both operands, compares them, and returns a true or false value after performing its test.

Let's introduce you to the less-than comparison operator. Like its mathematical counterpart's, its symbol is a less-than sign (<). This operator determines if the left operand is less than the right operand. The following code demonstrates the use of this operator:

5 < 6;

This reads as "Is 5 less than 6?" which of course is true. However, reversing the operands so that 6 is on the left and 5 is on the right (6 < 5) results in false.

JavaScript has many comparison operators, as the following table shows:

Comparison Operators

OPERATOR

NAME

DESCRIPTION

==

Equality

Tests if both operands are equal

===

Identity

Tests if both operands are equal and of the same type

!=

Inequality

Tests if both operands are not equal

!==

NonIdentity

Tests if both operands are not identical

<

Less Than

Tests if the left operand is less than the right operand

>

Greater Than

Tests if the left operand is greater than the right operand

<=

Less Than or Equal To

Tests if the left operand is less than or equal to the right operand

>=

Greater Than or Equal To

Tests if the left operand is greater than or equal to the right operand

Most of these operators are self-explanatory; the less-than, greater-than, less-than-or-equal-to, and greater-than-or-equal-to operators work the same way as their mathematical counterparts (with numbers, that is). However, the difference between the equality and identity operators, and between the inequality and nonidentity operators, isn't immediately obvious.

JavaScript's equality operator is lenient when comparing both operands; it coerces or converts the operands to the same type and then compares the converted values. Consider the following code:

"6" == 6; // true
"6" != 6; // false

The first line checks if a string value of "6" is equal to a numeric value of 6. Even though they look different, JavaScript says they are equal. The second line performs an inequality check: It determines if the string "6" is not the same as the number 6. Once again, looks can be deceiving. Even though the code compares a string with a number, JavaScript returns false because it converts both values and then compares them.

This is considered wrong in many programming circles, but thankfully this is where the identity and nonidentity operators come into play. These operators do not convert the operands to the same type. Instead, these operators leave the operands alone, and compare both operands' types and values. The following code performs the previous comparison, but instead uses the identical and not-identical operators:

"6" === 6; // false
"6" !== 6; // true

This is a more desirable result, and the use of the identity and nonidentity operators is therefore the recommended practice.

Operator Precedence

Like arithmetic operators, comparison operators have an order of precedence. The equality/inequality and identity/nonidentity operators have the lowest precedence, and the other comparison operators have the same higher level of precedence. This means that the less-than, greater-than, less-than-or-equal-to, and greater-than-or-equal-to operators perform their tests before the equality and identity operators perform theirs. Look at the following code for an example:

5 < 6 === true; // true

In this condition the less-than comparison is performed first since it has a higher precedence than the identical operator. The result of the less-than comparison is the Boolean value of true, which is then compared with the Boolean literal true. This condition can essentially be simplified as true === true. So the overall result of the condition is true.

Let's see another example:

false !== 6 >= 6; // true

Remember that the greater-than comparison has precedence over the identity comparison, so the 6 >= 6 comparison is made first. The number 6 is greater than or equal to 6, and the result of the comparison is true. With that conclusion, the overall condition can be simplified to false !== true, which of course is true, because false does not exactly equal true

Now look at a condition example involving some arithmetic operators:

3 * 4 > 11 + 2; // false

Comparison operators have a lower precedence than arithmetic operators. This means the arithmetic operations are performed before the comparison operation. After the arithmetic is performed, the condition is simplified to 12 > 13, which is false.

The previous examples have been relatively simple, and knowing the operator precedence rules certainly helps in deciphering each conditional statement and its outcome. However, using parentheses can make the conditional statements much clearer, as well as ensure that you don't get unexpected results. Look at the following lines:

(5 < 6) === true; // true
false !== (6 >= 6); // true
(3 * 4) > (11 + 2); // false

These three lines are rewrites of the three previous examples of conditional statements in this section. Adding parentheses ensures that precedence is clear, and that's important when you (or someone else) are maintaining code. As a general rule, use parentheses.

Finally, a note of caution about comparison operators: Using more than one comparison operator in a condition can cause unexpected results. Consider the following condition as an example and determine its outcome:

5 > 4 > 3;

If you said false, you are correct. At a glance, it looks like the condition tests whether 4 is less than 5 and greater than 3. In normal mathematical notation, that is correct, but that's not the case in JavaScript.

Let's break this down. First, the comparison operators in this condition are all > operators and have the same precedence. Therefore, this condition is evaluated from left to right. The first comparison checks if 5 is greater than 4. Remember that comparisons result in a true or false value. So the result of the 5 > 4 comparison is true, and the overall condition can be simplified to true > 3. This second comparison is obviously false, as true is not greater than 3, and that makes the final result of the conditional statement false.

But what if you want to perform a check such as: "Is 4 less than 5 and greater than 3?" This type of check has to be split into two conditions, such as 5 > 4 and 4 > 3. These two conditions are then combined into a single expression with a different set of operators called logical operators.

Logical Operators

Logical operators combine multiple conditions into one expression. JavaScript has three logical operators, and the following table lists them and their symbols:

Logical Operators

OPERATOR

NAME

&&

Logical AND

||

Logical OR

!

Logical NOT

It's important to note that the AND and OR operators use two ampersands (&) and pipes (|), respectively. Using just one gives you strange results, as a single & and a single | are JavaScript's bitwise operators — operators that work on individual bits.

Like comparison and arithmetic operators, the logical AND and OR operators operate on a left operand and a right operand. The primary difference between logical and comparison operators is that the logical operators operate on Boolean values, so both the left and the right values must evaluate to either true or false. Typically, one or both operands is a conditional statement. The logical NOT operator is a unary operator, but it too operates on a Boolean value.

The logical AND and OR operators have the lowest precedence. All other operations (mathematical and conditional) are performed before the logical AND and OR operators perform their jobs. The logical NOT operator, on the other hand, has a higher precedence than all other mathematical and conditional operators. Let's look at these operators in more detail, starting with logical AND.

Logical AND

The logical AND operator (&&) behaves very much like the English word and. For example, "Is 4 less than 5 and greater than 3?" There are two conditions in this statement. The left condition is "Is 4 less than 5?" and the right condition is "Is 4 greater than 3?" If both conditions result in true, then the entire statement must be true. But if one or both conditions results in false, then the entire statement cannot be true, and thus is false. Let's translate this into a conditional expression. The following conditional expression is the code equivalent of "Is 4 less than 5 and greater than 3?"

5 > 4 && 4 > 3;

With the logical AND operator, both the left and the right operand must evaluate to true in order for the entire expression to result in true. This code results in true because 5 is greater than 4, and 4 is greater than 3. But look at this next expression and determine its final outcome:

5 > 4 && 3 < 2;

If you said false, you are correct. The left operand, the 5 > 4 condition, results in true. The right operand, the 3 < 2 condition, results in false. Therefore, the result of the entire expression is false, because both operands are not true.

The following table is a truth table that outlines all possible outcomes of the logical AND operator:

Logical AND Truth Table

LEFT OPERAND

RIGHT OPERAND

RESULT

true

true

true

true

false

false

false

true

false

false

false

false

JavaScript doesn't want to do any more work than is absolutely necessary; it exhibits a behavior called short-circuiting. This means that the right operand is evaluated only if the left operand does not determine the outcome of the logical operation.

Looking at the truth table, you can see that the logical AND operation returns true if, and only if, both operands are true. If the left operand is true, JavaScript has to evaluate the right operand in order to determine whether the logical operation returns true or false. If the left operand is false, JavaScript automatically knows that the logical AND operation cannot return true, so it ceases the evaluation of the expression and returns false.

Logical OR

Like the logical AND operator, the logical OR operator (||) behaves somewhat like its English counterpart, the word or. In English, the word "or" is often implicitly exclusive. For example, the question "Do you want a cookie or a cupcake?" implies you can pick only one of those choices. Logical OR, however, is implicitly inclusive. Consider the following question: "Is 4 less than 5 or less than 3?" This phrase has two conditions. The one on the left is "Is 4 less than 5?" and the condition on the right is "Is 4 less than 3?" Like this question, a logical OR operation looks at both conditional operands and returns true if one or more of them is true. The following expression is the JavaScript equivalent of this "or" question:

5 > 4 || 4 < 3;

The first operand, 5 > 4, evaluates to true, but the second operand, 4 < 3, does not. Even so, this expression returns true because at least one of the operands is true.

Remember that a logical AND operation returns true only if both operands are true; all other outcomes are false. With the logical OR operation, the outcome is true unless both operands are false.

To make it a bit clearer, here is the truth table for the logical OR operator:

Logical OR Truth Table

LEFT OPERAND

RIGHT OPERAND

RESULT

true

true

true

true

false

true

false

true

true

false

false

false

Like the logical AND operator, the logical OR operator can short-circuit. If the left operand evaluates to true, JavaScript doesn't bother to evaluate the right operand and returns true. If the left operand evaluates to false, however, JavaScript will check the right operand to determine the OR operation's outcome.

Logical NOT

The logical NOT operator (!) is a little different from AND and OR. One difference, as mentioned earlier, is that it operates on only one operand — the one to the right of the operator. Another difference is that it reverses the Boolean value returned by that operand. This is a useful behavior, as you'll see when covering the if statement. Keeping those two things in mind, look at the following example of the logical NOT operator:

!(4 < 3);

If you were to read this expression in your native language, it would read "4 is not less than 3." By reading it that way, you of course know the expression is true. However, it's important to know how to determine the outcome of the statement without translating it into spoken language.

First evaluate the 4 < 3 condition. Its result is false, so the simplified version of this expression is !false. The logical NOT operator has the behavior of reversing whatever Boolean value its operand contains. In this case, it reverses false to true.

Following is the NOT operator's truth table:

Logical NOT Truth Table

RIGHT OPERAND

RESULT

true

false

false

true

Assigning the Results of Conditions

Up to this point, the examples of conditional statements have shown isolated expressions for the sake of simplicity. The results of conditional statements are Boolean values, so it's quite possible to store a condition's result in a variable. The following line of code shows this:

var conditionalOutcome = (4 < 3) || (3 > 2); // true

It's quite simple, really: just declare a variable, use the assignment operator, and put the conditional expression to the right of the equals sign.

EXECUTING CODE BASED ON CONDITIONS

You've been introduced to the core of decisions with conditional statements and expressions. Now it's time to use those concepts and apply them to actually making decisions within your code.

Aside from loops covered in Lesson 5, JavaScript has two constructs to make decisions. The first is the if statement and the second is the switch statement. You use these statements to execute code based on the outcome of a condition.

The if Statement

You'll find yourself using the if statement in almost every program you write; it works very much as it does in spoken language. For example, "If it is cold outside, Sally will put on her coat." This sentence says that Sally will put on her coat (an action) if it's cold outside (a condition). Translating this to JavaScript could look something like this:

if (weatherType === "cold") {
    putCoatOn();
}

This code assumes a variable of type string called weatherType. It shows the syntax of the if statement. Notice the lack of semicolons, except for the statement within the code block. An if statement is made up of the if keyword followed by a condition surrounded by parentheses. In the case of this code, the condition is a string comparison comparing the value of weatherType to the value "cold". If this condition results in true, the code within the code block executes. If it's false, the code block is skipped and JavaScript begins executing the next line of code after the code block.

What if you want to do the reverse: to check if it isn't cold outside and perform an action based on that outcome? There are a few different actions you could take. For one, you could use the !== operator to see if the weatherType variable is not "cold"; or you could use the logical NOT operator, like this:

if (!(weatherType === "cold")) {
    // do something for warm weather
}

This is where the logical NOT can be useful. This code uses it to reverse the result of the comparison operator. If the comparison's result is false, the logical NOT operator changes it to true and executes the warm-weather code. If the comparison's result is true (meaning cold weather), then the NOT alters the value to false, thus skipping the warm-weather code.

To execute code for cold or warm weather, you could write these two if statements sequentially, like this:

if (weatherType === "cold") {
    putCoatOn();
}

if (!(weatherType === "cold")) {
    // do something for warm weather
}

But JavaScript provides a cleaner way: the else statement. Like the if statement, the else statement translates very well into spoken language: "If it's cold outside, Sally will put on her coat, or else she'll wear clothes for warm weather." The following code demonstrates the use of the else statement:

if (weatherType === "cold") {
    putCoatOn();
} else {
    // do something for warm weather
}

As you can see here, the else statement is added after the closing curly brace of the if code block, and it too has its own block of code. The else statement cannot be used on its own; it must be used in conjunction with an if statement.

The example, so far, of how Sally prepares for the weather is all well and good if warm and cold are the only weather conditions to plan for, but it's quite evident that other weather patterns exist in this world. It could be raining or windy. The point is, a simple if ... else statement block isn't enough for this example; it needs to take several other weather patterns into consideration.

JavaScript is accommodating by allowing you to use an if statement immediately after an else The else if statement is used in conjunction with the if statement, but before the final else statement. It is used like an else statement while providing the ability to test another condition. So, in other words, it looks exactly like an if statement, except that it features the word else before if. The following example includes more weather possibilities for Sally:

if (weatherType === "cold") {
    putCoatOn();
} else if (weatherType === "rainy") {
    getUmbrella();
} else if (weatherType === "windy") {
    putOnJacket();
} else {
    // do something for warm weather
}

This code includes new checks for rainy and windy weather, and you can easily add more else if statements to check for other weather conditions. With if ... else if ... else you can turn a dumb calculator-type application into a thinking program, able to handle different types of situations. It's very useful for checking for various conditions.

In this example, each condition checked the value of one variable, the weatherType variable. In this case there's a more efficient means to achieve the same results: the switch statement.

The switch Statement

The switch statement is a switch of sorts. You supply it with a value or an expression, and it switches to the code that matches the supplied value or expression. There are four important parts of the switch statement:

  • The test expression

  • One or more case statements to check for possible values of the supplied test expression

  • The break statements

  • The default statement

The last example in the previous section, the if ... else if ... else example, can be rewritten with a switch statement, as follows:

switch (weatherType) {
    case "cold":
        putCoatOn();
        break;
    case "rainy":
        getUmbrella();
        break;
case "windy":
        putOnJacket();
        break;
    default:
        // do something for warm weather
        break;
}

The switch statement's test expression follows the switch keyword and is contained within parentheses. This code uses the weatherType variable as the test expression, but you can use any valid expression inside the parentheses.

Next are the case statements. The case statements do the condition checking by using the value in the case statement and checking if it is equal to the switch statement's test expression. For example, the first case statement in this example can be translated as if (weatherType == "cold"). Case statements end with a colon (:) and each case statement is paired with a break statement. The code in between the case statement and the break statement is executed if the test expression matches the case statement's condition.

The break keyword is used to break out of the switch statement when a case is matched and the code within the case is executed. It is possible to omit the break statement: Doing so causes code execution to drop to the next case statement. If this happens, the case's conditional value is ignored, and JavaScript executes all code until it reaches either a break statement or the end of the switch code block. The following example demonstrates this:

switch (true) {
    case true:
        alert("Hello");
    case false:
        alert("World");
}

Running this code results in an alert window displaying the text "Hello", because the first case statement matches the text expression (both values are true). After the user clicks OK to exit the alert window, code execution drops to the next case statement. JavaScript doesn't perform a check to see if false is equal to the test expression, but instead simply executes the code alert("World"). This results in another alert window displaying the text "World".

As a general rule of thumb, use the break keyword at the end of each case statement's block of code to break out of the switch statement. Otherwise you might experience some unexpected results.

The final piece of the switch statement is the special case statement called default. The default case does not use the case keyword, and is the code that executes when no matching case could be found. It is optional, as the previous example shows. If it is omitted, however, keep in mind that no code will execute if no matching case is found. It's generally a good idea to include a default case unless you are absolutely certain that you do not need it.

The case expressions in this section use literal values to determine the code that executes when a match is found.

The Ternary Operator

Sometimes you want to assign a value to a variable based on a condition. The common thought is to use an if ... else statement like this:

var someVariable = null;

if (4 < 5) {
    someVariable = "4 is less than 5.";
} else {
    someVariable = "4 isn't less than 5.";
}

There is nothing technically wrong with this code. You initialize a variable called someVariable with a value of null, and then you assign a string value to someVariable dependent upon the outcome of the if statement's condition. It does, however, require six lines of code to essentially assign a value to someVariable. Thankfully, there is a shorter way of performing this same exact process, and it uses the ternary operator to do it. The ternary operator's syntax looks like this:

(<condition>) ? <return value if true> : <return value if false>;

To convert the previous if ... else block to use the ternary operator, the code would look like the following:

var someVariable = (4 < 5) ? "4 is less than 5." : "4 isn't less than 5.";

The ternary operator is handy in situations like this where you want to assign or return a value based on a condition. It is, however, limited to only returning a single value; you cannot execute multiple statements in a ternary operation like you can with if ... else.

TRY IT

In this lesson, you learn about conditional statements and how to use them to make decisions with the if and switch statements, as well as the ternary operator.

Lesson Requirements

For this lesson, you need a text editor; any plain text editor will do. For Microsoft Windows users, Notepad is available by default on your system or you can download Microsoft's free Visual Web Developer Express (www.microsoft.com/express/web/) or Web Matrix (www.asp.net/webmatrix/). Mac OS X users can use TextMate, which comes as part of OS X, or download a trial for Coda (www.panic.com/coda/). Linux users can use the built-in VIM.

You also need a modern web browser. Choose any of the following:

  • Internet Explorer 8+

  • Google Chrome

  • Firefox 3.5+

  • Apple Safari 4+

  • Opera 10+

Create a subfolder called Lesson04 in the JS24Hour folder you created in Lesson 1. Store the files you create in this lesson in the Lesson04 folder.

Step-by-Step

Control code execution by using a condition to determine whether a number is less than three and greater than zero.

  1. Open your text editor, type the following code, and save the file as lesson04_sample01.js.

    var valueToTest = 2;
    
    if ((3 > valueToTest) && (valueToTest > 0)) {
        alert("The value is less than 3 and greater than 0");
    } else {
        alert("The value does not meet the needed criteria");
    }
  2. Open another instance of your text editor, type the following HTML, and save it as lesson04_sample01.htm:

    <html>
    <head>
        <title>Playing with if...else</title>
    </head>
    <body>
        <script type="text/javascript" src="lesson04_sample01.js"></script>
    </body>
    </html>
  3. Open the HTML file in your browser. You will see an alert window displaying the text "The value is less than 3 and greater than 0".

  4. Change the value of the valueToTest variable to any number greater than three, save the JavaScript file, and reload the page to see a different message.

In this next exercise, your script will be more dynamic and require user input via the prompt() function. You have not seen this function yet, but it is very simple.

  1. Open your text editor, type the following code, and save the file as lesson04_sample02.js.

    var weatherType = prompt("What is it like outside?", "");
    
    switch (weatherType) {
        case "sunny":
            alert("It's sunny outside! Go out and play!");
            break;
        case "rainy":
            alert("It's rainy outside! Stay inside!");
            break;
    case "cloudy":
            alert("It's cloudy outside. Stay in or go out.");
            break;
        case "windy":
            alert("It's windy outside! Carry a jacket!");
            break;
        case "cold":
            alert("It's cold outside! Don't forget your coat!");
            break;
        default:
            alert("I don't know that type of weather");
            break;
    
    }
  2. Open another instance of your text editor, type the following HTML, and save it as lesson04_sample02.htm:

    <html>
    <head>
        <title>Weather Program</title>
    </head>
    <body>
        <script type="text/javascript" src="lesson04_sample02.js"></script>
    </body>
    </html>
  3. Open the HTML file in your browser. A window will prompt you to answer a question. Answer the question and see how your program responds.

To get the sample database files, you can download Lesson 4 from the book's website at www.wrox.com.

Note

Please select Lesson 4 on the DVD to view the video that accompanies this lesson.

Step-by-Step
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.91.254