6. JavaScript: Control Statements II

OBJECTIVES

In this chapter you’ll learn:

• The essentials of counter-controlled repetition.

• To use the for and do…while repetition statements to execute statements in a program repeatedly.

• To perform multiple selection using the switch selection statement.

• To use the break and continue program-control statements

• To use the logical operators.

Not everything that can be counted counts, and not every thing that counts can be counted.
Albert Einstein

Who can control his fate?
William Shakespeare

The used key is always bright.
Benjamin Franklin

Intelligence … is the faculty of making artificial objects, especially tools to make tools.
Henri Bergson

Every advantage in the past is judged in the light of the final issue.
Demosthenes

6.1 Introduction

Chapter 5 began our introduction to control statements. In this chapter, we introduce JavaScript’s remaining control statements (with the exception of for…in, which is presented in Chapter 8). In later chapters, you’ll see that control structures are helpful in manipulating objects.

6.2 Essentials of Counter-Controlled Repetition

Counter-controlled repetition requires:

1. The name of a control variable (or loop counter).

2. The initial value of the control variable.

3. The increment (or decrement) by which the control variable is modified each time through the loop (also known as each iteration of the loop).

4. The condition that tests for the final value of the control variable to determine whether looping should continue.

To see the four elements of counter-controlled repetition, consider the simple script shown in Fig. 6.1, which displays lines of XHTML text that illustrate the seven different font sizes supported by XHTML. The declaration in line 12 names the control variable (counter), reserves space for it in memory and sets it to an initial value of 1. The declaration and initialization of counter could also have been accomplished by the following declaration and assignment statement:

var counter; // declare counter
counter = 1; // initialize counter to 1

Fig. 6.1 | Counter-controlled repetition. (Part 1 of 2.)

Image

Fig. 6.1 | Counter-controlled repetition. (Part 2 of 2.)

Image

Lines 16–18 in the while statement write a paragraph element consisting of the string "XHTML font size" concatenated with the control variable counter’s value, which represents the font size. An inline CSS style attribute sets the font-size property to the value of counter concatenated to ex. Note the use of the escape sequence ", which is placed around attribute style’s value. Because the double-quote character delimits the beginning and end of a string literal in JavaScript, it cannot be used in the contents of the string unless it is preceded by a to create the escape sequence ". For example, if counter is 5, the preceding statement produces the markup

<p style = "font-size: 5ex" > XHTML font size 5ex </p>

XHTML allows either single quotes (') or double quotes (") to be placed around the value specified for an attribute. JavaScript allows single quotes to be placed in a string literal. Thus, we could have placed single quotes around the font-size property to produce equivalent XHTML output without the use of escape sequences.

Image

Common Programming Error 6.1

Placing a double-quote (“) character inside a string literal that is delimited by double quotes causes a runtime error when the script is interpreted. To be displayed as part of a string literal, a double-quote (“) character must be preceded by a to form the escape sequence ”.

Line 19 in the while statement increments the control variable by 1 for each iteration of the loop (i.e., each time the body of the loop is performed). The loop-continuation condition (line 14) in the while statement tests whether the value of the control variable is less than or equal to 7 (the final value for which the condition is true). Note that the body of this while statement executes even when the control variable is 7. The loop terminates when the control variable exceeds 7 (i.e., counter becomes 8).

6.3 for Repetition Statement

The for repetition statement handles all the details of counter-controlled repetition. Figure 6.2 illustrates the power of the for statement by reimplementing the script of Fig. 6.1.

Fig. 6.2 | Counter-controlled repetition with the for statement. (Part 1 of 2.)

Image

Fig. 6.2 | Counter-controlled repetition with the for statement. (Part 2 of 2.)

Image

When the for statement begins executing (line 15), the control variable counter is declared and is initialized to 1 (i.e., the first statement of the for statement declares the control variable’s name and provides the control variable’s initial value). Next, the loop-continuation condition, counter <= 7, is checked. The condition contains the final value (7) of the control variable. The initial value of counter is 1. Therefore, the condition is satisfied (i.e., true), so the body statement (lines 16–18) writes a paragraph element in the XHTML document. Then, variable counter is incremented in the expression ++counter and the loop continues execution with the loop-continuation test. The control variable is now equal to 2, so the final value is not exceeded and the program performs the body statement again (i.e., performs the next iteration of the loop). This process continues until the control variable counter becomes 8, at which point the loop-continuation test fails and the repetition terminates.

The program continues by performing the first statement after the for statement. (In this case, the script terminates, because the interpreter reaches the end of the script.)

Figure 6.3 takes a closer look at the for statement at line 15 of Fig. 6.2. The for statement’s first line (including the keyword for and everything in parentheses after for) is often called the for statement header. Note that the for statement “does it all”—it specifies each of the items needed for counter-controlled repetition with a control variable.

Fig. 6.3 | for statement header components.

Image

Note that Fig. 6.3 uses the loop-continuation condition counter <= 7. If you incorrectly write counter < 7, the loop will execute only six times. This is an example of the common logic error called an off-by-one error.

Image

Common Programming Error 6.2

Using an incorrect relational operator or an incorrect final value of a loop counter in the condition of a while, for or do…while statement can cause an off-by-one error or an infinite loop.

Image

Error-Prevention Tip 6.1

Using the final value in the condition of a while or for statement and using the <= relational operator will help avoid off-by-one errors. For a loop used to print the values 1 to 10, for example, the initial value of counter should be 1, and the loop-continuation condition should be counter <= 10 rather than counter < 10 (which is an off-by-one error) or counter < 11 (which is correct). Many programmers, however, prefer so-called zero-based counting, in which, to count 10 times through the loop, counter would be initialized to zero and the loop-continuation test would be counter < 10.

The general format of the for statement is

for ( initialization; loopContinuationTest; increment )
    statements

where the initialization expression names the loop’s control variable and provides its initial value, loopContinuationTest is the expression that tests the loop-continuation condition (containing the final value of the control variable for which the condition is true), and increment is an expression that increments the control variable. The for statement can be represented by an equivalent while statement, with initialization, loopContinuationTest and increment placed as follows (Section 6.7 discusses an exception to this rule):

initialization;

while ( loopContinuationTest )
{
    statements
  increment;
}

If the initialization expression in the for statement’s header is the first definition of the control variable, the control variable can still be used after the for statement in the script. The part of a script in which a variable name can be used is known as the variable’s scope. Scope is discussed in detail in Chapter 7, JavaScript: Functions.

Image

Good Programming Practice 6.1

Place only expressions involving the control variable in the initialization and increment sections of a for statement. Manipulations of other variables should appear either before the loop (if they execute only once, like initialization statements) or in the loop body (if they execute once per iteration of the loop, like incrementing or decrementing statements).

The three expressions in the for statement are optional. If loopContinuationTest is omitted, JavaScript assumes that the loop-continuation condition is true, thus creating an infinite loop. One might omit the initialization expression if the control variable is initialized before the loop. One might omit the increment expression if the increment is calculated by statements in the body of the for statement or if no increment is needed. The increment expression in the for statement acts like a stand-alone statement at the end of the body of the for statement. Therefore, the expressions

counter = counter + 1
counter += 1
++counter
counter++

are all equivalent in the incrementing portion of the for statement. Many programmers prefer the form counter++. This is because the incrementing of the control variable occurs after the body of the loop is executed, and therefore the postincrementing form seems more natural. Preincrementing and postincrementing both have the same effect in our example, because the variable being incremented does not appear in a larger expression. The two semicolons in the for statement header are required.

Image

Common Programming Error 6.3

Using commas instead of the two required semicolons in the header of a for statement is a syntax error.

Image

Common Programming Error 6.4

Placing a semicolon immediately to the right of the right parenthesis of the header of a for statement makes the body of that for statement an empty statement. This code is normally a logic error.

The “increment” may be negative, in which case the loop counts downward. If the loop-continuation condition initially is false, the for statement’s body is not performed. Instead, execution proceeds with the statement following the for statement.

The control variable frequently is printed or used in calculations in the body of a for statement, but it does not have to be. Other times, the control variable is used for controlling repetition but never mentioned in the body of the for statement.

Image

Error-Prevention Tip 6.2

Although the value of the control variable can be changed in the body of a for statement, avoid changing it, because doing so can lead to subtle errors.

The for statement is flowcharted much like the while statement. For example, Fig. 6.4 shows the flowchart of the for statement

Fig. 6.4 | for repetition statement flowchart.

Image

for ( var counter = 1; counter <= 7; ++counter )
  document.writeln( "<p style = "font-size: " +
      counter + "ex">XHTML font size " + counter +
      "ex</p>" );

This flowchart makes it clear that the initialization occurs only once and that incrementing occurs after each execution of the body statement. Note that, besides small circles and arrows, the flowchart contains only rectangle symbols and a diamond symbol.

6.4 Examples Using the for Statement

The examples in this section show methods of varying the control variable in a for statement. In each case, we write the appropriate for header. Note the change in the relational operator for loops that decrement the control variable.

a)  Vary the control variable from 1 to 100 in increments of 1.

for (var i =1; i <=100; ++i )

b)  Vary the control variable from 100 to 1 in increments of -1 (i.e., decrements of 1).

for (var i =100; i >=1; --i )

c)  Vary the control variable from 7 to 77 in steps of 7.

for (var i =7; i <=77; i +=7 )

d)  Vary the control variable from 20 to 2 in steps of -2.

for (var i =20; i >=2; i -=2 )

e)  Vary the control variable over the following sequence of values: 2, 5, 8, 11, 14, 17, 20

for (var j =2; j <=20; j +=3 )

f)  Vary the control variable over the following sequence of values: 99, 88, 77, 66, 55, 44, 33, 22, 11, 0.

for (var j =99; j >=0; j -=11 )

Image

Common Programming Error 6.5

Not using the proper relational operator in the loop-continuation condition of a loop that counts downward (e.g., using i <= 1 in a loop that counts down to 1) is usually a logic error that will yield incorrect results when the program runs.

The next two scripts demonstrate the for repetition statement. Figure 6.5 uses the for statement to sum the even integers from 2 to 100. Note that the increment expression adds 2 to the control variable number after the body executes during each iteration of the loop. The loop terminates when number has the value 102 (which is not added to the sum).

Fig. 6.5 | Summation with the for repetition structure.

Image

Note that the body of the for statement in Fig. 6.5 actually could be merged into the rightmost (increment) portion of the for header by using a comma, as follows:

for (var number = 2; number <= 100; sum += number, number += 2)
    ;

Similarly, the initialization sum = 0 could be merged into the initialization section of the for statement.

Image

Good Programming Practice 6.2

Although statements preceding a for statement and in the body of a for statement can often be merged into the for header, avoid doing so, because it makes the program more difficult to read.

Image

Good Programming Practice 6.3

For clarity, limit the size of control-statement headers to a single line, if possible.

The next example computes compound interest (compounded yearly) using the for statement. Consider the following problem statement:

A person invests $1000.00 in a savings account yielding 5 percent interest. Assuming that all the interest is left on deposit, calculate and print the amount of money in the account at the end of each year for 10 years. Use the following formula to determine the amounts:

a = p(1 +r )n

where

p is the original amount invested (i.e., the principal)

r is the annual interest rate

n is the number of years

a is the amount on deposit at the end of the n th year.

This problem involves a loop that performs the indicated calculation for each of the 10 years the money remains on deposit. Figure 6.6 presents the solution to this problem, displaying the results in a table.

Fig. 6.6 | Compound interest calculation with a for loop. (Part 1 of 2.)

Image

Fig. 6.6 | Compound interest calculation with a for loop. (Part 2 of 2.)

Image

Lines 16–18 declare three variables and initialize principal to 1000.0 and rate to .05. Lines 20–21 write an XHTML <table> tag, and lines 22–23 write the caption that summarizes the table’s content. Lines 24–25 create the table’s header section (<thead>), a row (<tr>) and a column heading (<th>) containing “Year.” Lines 26–28 create a table heading for “Amount on deposit” and write the closing </tr> and </thead> tags.

The for statement (lines 31–37) executes its body 10 times, incrementing control variable year from 1 to 10 (note that year represents n in the problem statement). Java-Script does not include an exponentiation operator. Instead, we use the Math object’s pow method for this purpose. Math.pow(x, y) calculates the value of x raised to the yth power. Method Math.pow takes two numbers as arguments and returns the result.

Line 33 performs the calculation using the formula given in the problem statement. Lines 34–36 write a line of XHTML markup that creates another row in the table. The first column is the current year value. The second column displays the value of amount. Line 39 writes the closing </tbody> and </table> tags after the loop terminates.

Line 35 introduces the Number object and its toFixed method. The variable amount contains a numerical value, so JavaScript represents it as a Number object. The toFixed method of a Number object formats the value by rounding it to the specified number of decimal places. In line 35, amount.toFixed(2) outputs the value of amount with two decimal places.

Variables amount, principal and rate represent numbers in this script. Remember that JavaScript represents all numbers as floating-point numbers. This feature is convenient in this example, because we are dealing with fractional parts of dollars and need a type that allows decimal points in its values.

A Caution about Using Floating Point Numbers for Monetary Amounts

Unfortunately, floating-point numbers can cause trouble. Here is a simple example of what can go wrong when using floating-point numbers to represent dollar amounts (assuming that dollar amounts are displayed with two digits to the right of the decimal point): Two dollar amounts stored in the machine could be 14.234 (which would normally be rounded to 14.23 for display purposes) and 18.673 (which would normally be rounded to 18.67 for display purposes). When these amounts are added, they produce the internal sum 32.907, which would normally be rounded to 32.91 for display purposes. Thus your printout could appear as

Image

but a person adding the individual numbers as printed would expect the sum to be 32.90. You have been warned!

6.5 switch Multiple-Selection Statement

Occasionally, an algorithm will contain a series of decisions in which a variable or expression is tested separately for each of the values it may assume, and different actions are taken for each value. JavaScript provides the switch multiple-selection statement to handle such decision making. The script in Fig. 6.7 demonstrates three different CSS list formats determined by the value the user enters.

Fig. 6.7 | Using the switch multiple-selection statement. (Part 1 of 4.)

Image

Fig. 6.7 | Using the switch multiple-selection statement. (Part 2 of 4.)

Image

Fig. 6.7 | Using the switch multiple-selection statement. (Part 3 of 4.)

Image

Fig. 6.7 | Using the switch multiple-selection statement. (Part 4 of 4.)

Image

Line 12 in the script declares the variable choice. This variable stores the user’s choice, which determines what type of XHTML list to display. Lines 13–14 declare variables startTag and endTag, which will store the XHTML tags that will be used to create the list element. Line 15 declares variable validInput and initializes it to true. The script uses this variable to determine whether the user made a valid choice (indicated by the value of true). If a choice is invalid, the script sets validInput to false. Line 16 declares variable listType, which will store an h1 element indicating the list type. This heading appears before the list in the XHTML document.

Lines 18–19 prompt the user to enter a 1 to display a numbered list, a 2 to display a lettered list and a 3 to display a list with roman numerals. Lines 21–40 define a switch statement that assigns to the variables startTag, endTag and listType values based on the value input by the user in the prompt dialog. We create these different lists using the CSS property list-style-type, which allows us to set the numbering system for the list. Possible values include decimal (numbers—the default), lower-roman (lowercase Roman numerals), upper-roman (uppercase Roman numerals), lower-alpha (lowercase letters), upper-alpha (uppercase letters), and several others.

The switch statement consists of a series of case labels and an optional default case. When the flow of control reaches the switch statement, the script evaluates the controlling expression (choice in this example) in the parentheses following keyword switch. The value of this expression is compared with the value in each of the case labels, starting with the first case label. Assume that the user entered 2. Remember that the value typed by the user in a prompt dialog is returned as a string. So, the string 2 is compared to the string in each case in the switch statement. If a match occurs (case "2":), the statements for that case execute. For the string 2 (lines 29–32), we set startTag to an opening ol tag with the style property list-style-type set to upper-alpha, set endTag to "</ol>" to indicate the end of an ordered list and set listType to "<h1>Lettered List</h1>". If no match occurs between the controlling expression’s value and a case label, the default case executes and sets variable validInput to false.

The break statement in line 32 causes program control to proceed with the first statement after the switch statement. The break statement is used because the cases in a switch statement would otherwise run together. If break is not used anywhere in a switch statement, then each time a match occurs in the statement, the statements for all the remaining cases execute.

Next, the flow of control continues with the if statement in line 42, which tests variable validInput to determine whether its value is true. If so, lines 44–49 write the list-Type, the startTag, three list items (<li>) and the endTag. Otherwise, the script writes text in the XHTML document indicating that an invalid choice was made (line 52).

Each case can have multiple actions (statements). The switch statement is different from others in that braces are not required around multiple actions in a case of a switch. The general switch statement (i.e., using a break in each case) is flowcharted in Fig. 6.8. [Note: As an exercise, flowchart the general switch statement without break statements.]

Fig. 6.8 | switch multiple-selection statement.

Image

The flowchart makes it clear that each break statement at the end of a case causes control to exit from the switch statement immediately. The break statement is not required for the last case in the switch statement (or the default case, when it appears last), because program control automatically continues with the next statement after the switch statement.

Image

Common Programming Error 6.6

Forgetting a break statement when one is needed in a switch statement is a logic error.

Image

Software Engineering Observation 6.1

Provide a default case in switch statements. Cases not explicitly tested in a switch statement without a default case are ignored. Including a default case focuses you on processing exceptional conditions. However, there are situations in which no default processing is needed.

Image

Good Programming Practice 6.4

Although the case clauses and the default case clause in a switch statement can occur in any order, it is clearer (and more common) to place the default clause last.

Image

Good Programming Practice 6.5

In a switch statement, when the default clause is listed last, its break statement is not required. Some programmers include this break for clarity and for symmetry with other cases.

Note that having several case labels listed together (e.g., case 1: case 2: with no statements between the cases) performs the same set of actions for each case.

6.6 do…while Repetition Statement

The do…while repetition statement is similar to the while statement. In the while statement, the loop-continuation test occurs at the beginning of the loop, before the body of the loop executes. The do…while statement tests the loop-continuation condition after the loop body executes—therefore, the loop body always executes at least once. When a do…while terminates, execution continues with the statement after the while clause. Note that it is not necessary to use braces in a do…while statement if there is only one statement in the body. However, the braces usually are included, to avoid confusion between the while and do…while statements. For example,

while ( condition )

normally is regarded as the header to a while statement. A do…while statement with no braces around a single-statement body appears as

do
      statement
while ( condition );

which can be confusing. The last line—while( condition );—may be misinterpreted as a while statement containing an empty statement (the semicolon by itself). Thus, to avoid confusion, the do…while statement with a one-statement body is often written as follows:

do
{
    statement
} while ( condition );

Image

Good Programming Practice 6.6

Some programmers always include braces in a do…while statement even if they are not necessary. This helps eliminate ambiguity between the while statement and the do…while statement containing a one-statement body.

Image

Error-Prevention Tip 6.3

Infinite loops are caused when the loop-continuation condition never becomes false in a while, for or do…while statement. To prevent this, make sure that there is not a semicolon immediately after the header of a while or for statement. In a counter-controlled loop, make sure that the control variable is incremented (or decremented) in the body of the loop. In a sentinel-controlled loop, make sure that the sentinel value is eventually input.

The script in Fig. 6.9 uses a do…while statement to display each of the six different XHTML heading types (h1 through h6). Line 12 declares control variable counter and initializes it to 1. Upon entering the do…while statement, lines 15–17 write a line of XHTML text in the document. The value of control variable counter is used to create the starting and ending header tags (e.g., <h1> and </h1>) and to create the line of text to display (e.g., This is an h1 level head). Line 18 increments the counter before the loop-continuation test occurs at the bottom of the loop.

Fig. 6.9 | Using the do…while repetition statement.

Image

The do…while flowchart in Fig. 6.10 makes it clear that the loop-continuation test does not occur until the action executes at least once.

Fig. 6.10 | do…while repetition statement flowchart.

Image

6.7 break and continue Statements

The break and continue statements alter the flow of control. The break statement, when executed in a while, for, do…while or switch statement, causes immediate exit from the statement. Execution continues with the first statement after the structure. The break statement is commonly used to escape early from a loop or to skip the remainder of a switch statement (as in Fig. 6.7). Figure 6.11 demonstrates the break statement in a for repetition statement.

Fig. 6.11 | Using the break statement in a for statement. (Part 1 of 2.)

Image

Fig. 6.11 | Using the break statement in a for statement. (Part 2 of 2.)

Image

During each iteration of the for statement in lines 14–20, the script writes the value of count in the XHTML document. When the if statement in line 16 detects that count is 5, the break in line 17 executes. This statement terminates the for statement, and the program proceeds to line 22 (the next statement in sequence immediately after the for statement), where the script writes the value of count when the loop terminated (i.e., 5). The loop executes line 19 only four times.

The continue statement, when executed in a while, for or do…while statement, skips the remaining statements in the body of the statement and proceeds with the next iteration of the loop. In while and do…while statements, the loop-continuation test evaluates immediately after the continue statement executes. In for statements, the increment expression executes, then the loop-continuation test evaluates. This is the one case in which for and while differ. Improper placement of continue before the increment in a while may result in an infinite loop.

Figure 6.12 uses continue in a for statement to skip the document.writeln statement in line 20 when the if statement in line 17 determines that the value of count is 5. When the continue statement executes, the script skips the remainder of the for statement’s body. Program control continues with the increment of the for statement’s control variable, followed by the loop-continuation test to determine whether the loop should continue executing.

Fig. 6.12 | Using the continue statement in a for statement. (Part 1 of 2.)

Image

Fig. 6.12 | Using the continue statement in a for statement. (Part 2 of 2.)

Image

Image

Software Engineering Observation 6.2

Some programmers feel that break and continue violate structured programming. They do not use break and continue, because the effects of these statements can be achieved by structured programming techniques.

Image

Performance Tip 6.1

The break and continue statements, when used properly, perform faster than the corresponding structured techniques.

Image

Software Engineering Observation 6.3

There is a tension between achieving quality software engineering and achieving the best-performing software. Often, one of these goals is achieved at the expense of the other. For all but the most performance-intensive situations, the following rule of thumb should be followed: First make your code simple, readable and correct; then make it fast and small, but only if necessary.

6.8 Labeled break and continue Statements

The break statement can break out of an immediately enclosing while, for, do…while or switch statement. To break out of a nested set of structures, you can use the labeled break statement. This statement, when executed in a while, for, do…while or switch statement, causes immediate exit from that statement and any number of enclosing repetition statements; program execution resumes with the first statement after the enclosing labeled statement (a statement preceded by a label). The labeled statement can be a block (a set of statements enclosed in curly braces, {}). Labeled break statements commonly are used to terminate nested looping structures containing while, for, do…while or switch statements. Figure 6.13 demonstrates the labeled break in a nested for statement.

Fig. 6.13 | Labeled break statement in a nested for statement. (Part 1 of 2.)

Image

Fig. 6.13 | Labeled break statement in a nested for statement. (Part 2 of 2.)

Image

The labeled block (lines 12–28) begins with a label (an identifier followed by a colon). Here, we use the label stop:. The block is enclosed between the braces at the end of line 12 and in line 28, and includes both the nested for statement starting in line 13 and the document.writeln statement in line 27. When the if statement in line 17 detects that row is equal to 5, the statement in line 18 executes. This statement terminates both the for statement in line 15 and its enclosing for statement in line 13, and the program proceeds to the statement in line 30 (the first statement in sequence after the labeled block). The inner for statement executes its body only four times. Note that the document.writeln statement in line 27 never executes, because it is included in the labeled block and the outer for statement never completes.

The continue statement proceeds with the next iteration (repetition) of the immediately enclosing while, for or do…while statement. The labeled continue statement, when executed in a repetition statement (while, for or do…while), skips the remaining statements in the structure’s body and any number of enclosing repetition statements, then proceeds with the next iteration of the enclosing labeled repetition statement (a repetition statement preceded by a label). In labeled while and do…while statements, the loop-continuation test evaluates immediately after the continue statement executes. In a labeled for statement, the increment expression executes, then the loop-continuation test evaluates. Figure 6.14 uses the labeled continue statement in a nested for statement to cause execution to continue with the next iteration of the outer for statement.

Fig. 6.14 | Labeled continue statement in a nested for statement. (Part 1 of 2.)

Image

Fig. 6.14 | Labeled continue statement in a nested for statement. (Part 2 of 2.)

Image

The labeled for statement (lines 13–24) starts with the nextRow label in line 12. When the if statement in line 19 in the inner for statement detects that column is greater than row, line 20 executes and program control continues with the increment of the control variable of the outer for statement. Even though the inner for statement counts from 1 to 10, the number of * characters output on a row never exceeds the value of row.

6.9 Logical Operators

So far, we have studied only such simple conditions as count <= 10, total > 1000 and number != sentinelValue. These conditions were expressed in terms of the relational operators >, <, >= and <=, and in terms of the equality operators == and !=. Each decision tested one condition. To make a decision based on multiple conditions, we performed these tests in separate statements or in nested if or if...else statements.

JavaScript provides logical operators that can be used to form more complex conditions by combining simple conditions. The logical operators are && (logical AND), || (logical OR) and ! (logical NOT, also called logical negation). We consider examples of each of these operators.

Suppose that, at some point in a program, we wish to ensure that two conditions are both true before we choose a certain path of execution. In this case, we can use the logical && operator, as follows:

if ( gender == 1 && age >= 65 )
   ++seniorFemales;

This if statement contains two simple conditions. The condition gender == 1 might be evaluated to determine, for example, whether a person is a female. The condition age >= 65 is evaluated to determine whether a person is a senior citizen. The if statement then considers the combined condition

gender == 1 && age >=65

This condition is true if and only if both of the simple conditions are true. Finally, if this combined condition is indeed true, the count of seniorFemales is incremented by 1. If either or both of the simple conditions are false, the program skips the incrementing and proceeds to the statement following the if statement. The preceding combined condition can be made more readable by adding redundant parentheses:

( gender == 1 ) && ( age >=65 )

The table in Fig. 6.15 summarizes the && operator. The table shows all four possible combinations of false and true values for expression1 and expression2. Such tables are often called truth tables. JavaScript evaluates to false or true all expressions that include relational operators, equality operators and/or logical operators.

Fig. 6.15 | Truth table for the && (logical AND) operator.

Image

Now let us consider the || (logical OR) operator. Suppose we wish to ensure that either or both of two conditions are true before we choose a certain path of execution. In this case, we use the || operator, as in the following program segment:

if ( semesterAverage >= 90 || finalExam >= 90 )
   document.writeln( "Student grade is A" );

This statement also contains two simple conditions. The condition semesterAverage >= 90 is evaluated to determine whether the student deserves an “A” in the course because of a solid performance throughout the semester. The condition finalExam >= 90 is evaluated to determine whether the student deserves an “A” in the course because of an outstanding performance on the final exam. The if statement then considers the combined condition

semesterAverage >=90 || finalExam >=90

and awards the student an “A” if either or both of the simple conditions are true. Note that the message "Student grade is A" is not printed only when both of the simple conditions are false. Figure 6.16 is a truth table for the logical OR operator (||).

Fig. 6.16 | Truth table for the || (logical OR) operator.

Image

The && operator has a higher precedence than the || operator. Both operators associate from left to right. An expression containing && or || operators is evaluated only until truth or falsity is known. Thus, evaluation of the expression

gender == 1 && age >=65

stops immediately if gender is not equal to 1 (i.e., the entire expression is false) and continues if gender is equal to 1 (i.e., the entire expression could still be true if the condition age >= 65 is true). Similarly, the || operator immediately returns true if the first operand is true. This performance feature for evaluation of logical AND and logical OR expressions is called short-circuit evaluation.

JavaScript provides the ! (logical negation) operator to enable a programmer to “reverse” the meaning of a condition (i.e., a true value becomes false, and a false value becomes true). Unlike the logical operators && and ||, which combine two conditions (i.e., they are binary operators), the logical negation operator has only a single condition as an operand (i.e., it is a unary operator). The logical negation operator is placed before a condition to choose a path of execution if the original condition (without the logical negation operator) is false, as in the following program segment:

if ( ! ( grade == sentinelValue ) )
   document.writeln( "The next grade is " + grade );

The parentheses around the condition grade == sentinelValue are needed, because the logical negation operator has a higher precedence than the equality operator. Figure 6.17 is a truth table for the logical negation operator.

Fig. 6.17 | Truth table for operator ! (logical negation).

Image

In most cases, you can avoid using logical negation by expressing the condition differently with an appropriate relational or equality operator. For example, the preceding statement may also be written as follows:

if ( grade != sentinelValue )
  document.writeln( "The next grade is " + grade );

The script in Fig. 6.18 demonstrates all the logical operators by producing their truth tables. The script produces an XHTML table containing the results.

Fig. 6.18 | Demonstrating logical operators. (Part 1 of 2.)

Image

Fig. 6.18 | Demonstrating logical operators. (Part 2 of 2.)

Image

In the output of Fig. 6.18, the strings "false" and "true" indicate false and true for the operands in each condition. The result of the condition is shown as true or false. Note that when you use the concatenation operator with a boolean value and a string, JavaScript automatically converts the boolean value to string "false" or "true". Lines 16–39 build an XHTML table containing the results.

An interesting feature of JavaScript is that most nonboolean values can be converted to boolean true or false values. Nonzero numeric values are considered to be true. The numeric value zero is considered to be false. Any string that contains characters is considered to be true. The empty string (i.e., the string containing no characters) is considered to be false. The value null and variables that have been declared but not initialized are considered to be false. All objects (e.g., the browser’s document and window objects and JavaScript’s Math object) are considered to be true.

Figure 6.19 shows the precedence and associativity of the JavaScript operators introduced up to this point. The operators are shown top to bottom in decreasing order of precedence.

Fig. 6.19 | Precedence and associativity of the operators discussed so far.

Image

..................Content has been hidden....................

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