5. JavaScript: Control Statements I

OBJECTIVES

In this chapter you’ll learn:

• To use the if and if...else selection statements to choose among alternative actions.

• To use the while repetition statement to execute statements in a script repeatedly.

• Counter-controlled repetition and sentinel-controlled repetition.

• To use the increment, decrement and assignment operators.

Let’s all move one place on.
—Lewis Carrol

The wheel is come full circle.
—William Shakespeare

How many apples fell on Newton’s head before he took the hint!
—Robert Frost

5.1 Introduction

When writing a script, it is essential to understand the types of building blocks that are available and to employ proven program-construction principles. In this chapter and in Chapter 6, we discuss JavaScript’s control statements, which are similar to those in many other high-level languages. We also introduce JavaScript’s assignment operators and explore its increment and decrement operators. These additional operators abbreviate and simplify many program statements.

5.2 Control Statements

JavaScript provides three types of selection statements; we discuss each in this chapter and in Chapter 6. The if selection statement performs (selects) an action if a condition is true or skips the action if the condition is false. The if...else selection statement qperforms an action if a condition is true and performs a different action if the condition is false. The switch selection statement (Chapter 6) performs one of many different actions, depending on the value of an expression.

The if statement is called a single-selection statement because it selects or ignores a single action (or, as we’ll soon see, a single group of actions). The if...else statement is a double-selection statement because it selects between two different actions (or groups of actions). The switch statement is a multiple-selection statement because it selects among many different actions (or groups of actions).

JavaScript provides four repetition statement types, namely while, do...while, for and for...in. (do...while and for are covered in Chapter 6; for...in is covered in Chapter 8.) Each of the words if, else, switch, while, do, for and in is a JavaScript keyword. These words are reserved by the language to implement various features, such as JavaScript’s control statements. Keywords cannot be used as identifiers (e.g., for variable names). A list of JavaScript keywords is shown in Fig. 5.1.

Fig. 5.1 | JavaScript keywords.

Image

Image

Common Programming Error 5.1

Using a keyword as an identifier is a syntax error.

As we have shown, JavaScript has only eight control structures: sequence, three types of selection and four types of repetition. A program is formed by combining control statements as necessary to implement the program’s algorithm.

Single-entry/single-exit control statements make it easy to build programs; the control statements are attached to one another by connecting the exit point of one to the entry point of the next. This process is called control-statement stacking. We’ll learn that there is only one other way in which control statements may be connected—control-statement nesting. Thus JavaScript programs are constructed from only eight different types of control statements combined in only two ways.

5.3 if Selection Statement

A selection statement is used to choose among alternative courses of action in a program. For example, suppose that the passing grade on an examination is 60 (out of 100). Then the JavaScript statement

if ( studentGrade >= 60 )
   document.writeln( "Passed" );

determines whether the condition “student’s grade is greater than or equal to 60” is true or false. If the condition is true, then "Passed" is output in the XHTML document, and the next JavaScript statement in order is performed. If the condition is false, the print statement is ignored, and the next JavaScript statement in order is performed.

Note that the second line of this selection statement is indented. The JavaScript interpreter ignores white-space characters—blanks, tabs and newlines used for indentation and vertical spacing.

The flowchart in Fig. 5.2 illustrates the single-selection if statement. This flowchart contains what is perhaps the most important flowcharting symbol—the diamond symbol (or decision symbol), which indicates that a decision is to be made. The decision symbol contains an expression, such as a condition, that can be either true or false. The decision symbol has two flowlines emerging from it. One indicates the path to follow in the program when the expression in the symbol is true; the other indicates the path to follow in the program when the expression is false. A decision can be made on any expression that evaluates to a value of JavaScript’s boolean type (i.e., any expression that evaluates to true or false—also known as a boolean expression).

Fig. 5.2 | Flowcharting the single-selection if statement.

Image

Image

Software Engineering Observation 5.1

In JavaScript, any nonzero numeric value in a condition evaluates to true, and 0 evaluates to false. For strings, any string containing one or more characters evaluates to true, and the empty string (the string containing no characters, represented as “”) evaluates to false. Also, a variable that has been declared with var but has not been assigned a value evaluates to false.

Note that the if statement is a single-entry/single-exit control statement. Flowcharts for the remaining control statements also contain (besides small circle symbols and flow-lines) only rectangle symbols, to indicate the actions to be performed, and diamond symbols, to indicate decisions to be made. This type of flowchart represents the action/decision model of programming.

5.4 if…else Selection Statement

The if selection statement performs an indicated action only when the condition evaluates to true; otherwise, the action is skipped. The if…else selection statement allows you to specify that a different action is to be performed when the condition is true than when the condition is false. For example, the JavaScript statement

if ( studentGrade >= 60 )
   document.writeln( "Passed"  );
else
   document.writeln( "Failed"  );

outputs Passed in the XHTML document if the student’s grade is greater than or equal to 60 and outputs Failed if the student’s grade is less than 60. In either case, after printing occurs, the next JavaScript statement in sequence (i.e., the next statement after the whole if...else statement) is performed. Note that the body of the else part of the structure is also indented. The flowchart shown in Fig. 5.3 illustrates the if...else selection state-ment’s flow of control.

Fig. 5.3 | Flowcharting the double-selection if...else statement.

Image

JavaScript provides an operator, called the conditional operator (?:), that is closely related to the if...else statement. The operator ?: is JavaScript’s only ternary operator—it takes three operands. The operands together with the ?: form a conditional expression. The first operand is a boolean expression, the second is the value for the conditional expression if the expression evaluates to true and the third is the value for the conditional expression if the expression evaluates to false. For example, consider the following statement

document.writeln( studentGrade >= 60 ? "Passed" : "Failed" );

contains a conditional expression that evaluates to the string "Passed" if the condition studentGrade >= 60 is true and evaluates to the string "Failed" if the condition is false. Thus, this statement with the conditional operator performs essentially the same operation as the preceding if...else statement. The precedence of the conditional operator is low, so the entire conditional expression is normally placed in parentheses to ensure that it evaluates correctly.

Nested if…else statements test for multiple cases by placing if...else statements inside if...else statements. For example, the following pseudocode statement indicates that the program should print A for exam grades greater than or equal to 90, B for grades in the range 80 to 89, C for grades in the range 70 to 79, D for grades in the range 60 to 69 and F for all other grades:

if ( studentGrade >= 90 )
   document.writeln( "A" );
else
   if ( studentGrade >= 80 )
      document.writeln( "B" );
   else
      if ( studentGrade >= 70 )
         document.writeln( "C" );
      else
         if ( studentGrade >= 60 )
            document.writeln( "D"  );
         else
            document.writeln( "F"  );

If studentGrade is greater than or equal to 90, all four conditions will be true, but only the document.writeln statement after the first test will execute. After that particular document.writeln executes, the else part of the outer if...else statements is skipped.

Image

Good Programming Practice 5.1

If there are several levels of indentation, each level should be indented the same additional amount of space.

Most JavaScript programmers prefer to write the preceding if statement as

if ( grade >= 90 )
   document.writeln( "A"  );
else if ( grade >= 80  )
   document.writeln( "B"  );
else if ( grade >= 70  )
   document.writeln( "C"  );
else if ( grade >= 60  )
   document.writeln( "D"  );
else
   document.writeln( "F"  );

The two forms are equivalent. The latter form is popular because it avoids the deep indentation of the code to the right. Such deep indentation often leaves little room on a line, forcing lines to be split and decreasing program readability.

It is important to note that the JavaScript interpreter always associates an else with the previous if, unless told to do otherwise by the placement of braces ({}). This situation is referred to as the dangling-else problem. For example,

if ( x > 5 )
   if ( y > 5 )
      document.writeln( "x and y are > 5" );
else
   document.writeln( "x is <= 5" );

appears to indicate with its indentation that if x is greater than 5, the if statement in its body determines whether y is also greater than 5. If so, the body of the nested if statement outputs the string "x and y are > 5". Otherwise, it appears that if x is not greater than 5, the else part of the if...else statement outputs the string "x is <= 5".

Beware! The preceding nested if statement does not execute as it appears. The interpreter actually interprets the preceding statement as

if ( x > 5 )
   if ( y > 5 )
      document.writeln( "x and y are > 5" );
   else
      document.writeln( "x is <= 5" );

in which the body of the first if statement is a nested if...else statement. This statement tests whether x is greater than 5. If so, execution continues by testing whether y is also greater than 5. If the second condition is true, the proper string—"x and y are > 5"—is displayed. However, if the second condition is false, the string "x is <= 5" is displayed, even though we know that x is greater than 5.

To force the preceding nested if statement to execute as it was intended originally, it must be written as follows:

if ( x > 5 )
{
   if ( y > 5 )
      document.writeln( "x and y are > 5" );
}
else
   document.writeln( "x is <= 5" );

The braces ({}) indicate to the interpreter that the second if statement is in the body of the first if statement and that the else is matched with the first if statement.

The if selection statement expects only one statement in its body. To include several statements in an if statement’s body, enclose the statements in braces ({ and }). This can also be done in the else section of an if...else statement. A set of statements contained within a pair of braces is called a block.

Image

Software Engineering Observation 5.2

A block can be placed anywhere in a program that a single statement can be placed.

Image

Software Engineering Observation 5.3

Unlike individual statements, a block does not end with a semicolon. However, each statement within the braces of a block should end with a semicolon.

The following example includes a block in the else part of an if...else statement:

if ( grade >= 60 )
   document.writeln( "Passed" );
else
{
   document.writeln( "Failed<br />" );
   document.writeln( "You must take this course again." );
}

In this case, if grade is less than 60, the program executes both statements in the body of the else and prints

Failed.
You must take this course again.

Note the braces surrounding the two statements in the else clause. These braces are important. Without them, the statement

document.writeln("You must take this course again." );

would be outside the body of the else part of the if and would execute regardless of whether the grade is less than 60.

Image

Common Programming Error 5.2

Forgetting one or both of the braces that delimit a block can lead to syntax errors or logic errors.

Image

Good Programming Practice 5.2

Some programmers prefer to type the beginning and ending braces of blocks before typing the individual statements within the braces. This helps avoid omitting one or both of the braces.

Image

Software Engineering Observation 5.4

Just as a block can be placed anywhere a single statement can be placed, it is also possible to have no statement at all (the empty statement) in such places. The empty statement is represented by placing a semicolon (;) where a statement would normally be.

Image

Common Programming Error 5.3

Placing a semicolon after the condition in an if statement leads to a logic error in single-selection if statement and a syntax error in double-selection if statements (if the if part contains a nonempty body statement).

5.5 while Repetition Statement

A repetition statement allows you to specify that a script is to repeat an action while some condition remains true.

Image

Common Programming Error 5.4

If the body of a while statement never causes the while statement’s condition to become true, a logic error occurs. Normally, such a repetition structure will never terminate—an error called an infinite loop. Both Internet Explorer and Firefox show a dialog allowing the user to terminate a script that contains an infinite loop.

Image

Common Programming Error 5.5

Remember that JavaScript is a case-sensitive language. In code, spelling the keyword while with an uppercase W, as in While, is a syntax error. All of JavaScript’s reserved keywords, such as while, if and else, contain only lowercase letters.

As an example of a while statement, consider a program segment designed to find the first power of 2 larger than 1000. Variable product begins with the value 2:

var product = 2;

while ( product <= 1000  )
   product = 2  * product;

When the while statement finishes executing, product contains the result 1024. The flowchart in Fig. 5.4 illustrates the flow of control of the preceding while statement.

Fig. 5.4 | Flowcharting the while repetition statement.

Image

When the script enters the while statement, product is 2. The script repeatedly multiplies variable product by 2, so product takes on the values 4, 8, 16, 32, 64, 128, 256, 512 and 1024 successively. When product becomes 1024, the condition product <= 1000 in the while statement becomes false. This terminates the repetition, with 1024 as product’s final value. Execution continues with the next statement after the while statement. [Note: If a while statement’s condition is initially false, the body statement(s) will never execute.]

5.6 Counter-Controlled Repetition

Consider the following problem statement:

A class of ten students took a quiz. The grades (integers in the range 0 to 100) for this quiz are available to you. Determine the class average on the quiz.

The class average is equal to the sum of the grades divided by the number of students (10 in this case). The program for this problem (Fig. 5.5) must input each of the grades, perform the averaging calculation and display the result. We use counter-controlled repetition to input the grades one at a time. In this example, repetition terminates when the counter exceeds 10.

Fig. 5.5 | Counter-controlled repetition to calculate a class average. (Part 1 of 2.)

Image

Fig. 5.5 | Counter-controlled repetition to calculate a class average. (Part 2 of 2.)

Image

Lines 12–16 declare variables total, gradeCounter, grade, gradeValue, average. The variable grade will store the string the user types into the prompt dialog. The variable gradeValue will store the integer value of the grade the user enters into the prompt dialog.

Lines 19–20 are assignment statements that initialize total to 0 and gradeCounter to 1. Note that variables total and gradeCounter are initialized before they are used in a calculation.

Image

Common Programming Error 5.6

Not initializing a variable that will be used in a calculation results in a logic error that produces the value NaN—Not a Number. You must initialize the variable before it is used in a calculation.

Line 23 indicates that the while statement continues iterating while the value of gradeCounter is less than or equal to 10. Line 27 corresponds to the pseudocode statement “Input the next grade.” The statement displays a prompt dialog with the prompt "Enter integer grade:" on the screen.

After the user enters the grade, line 30 converts it from a string to an integer. We must convert the string to an integer in this example; otherwise, the addition statement in line 33 will be a string-concatenation statement rather than a numeric sum.

The program now is ready to increment the variable gradeCounter to indicate that a grade has been processed and to read the next grade from the user. Line 36 adds 1 to gradeCounter, so the condition in the while statement will eventually become false and terminate the loop. After this statement executes, the program continues by testing the condition in the while statement in line 23. If the condition is still true, the statements in lines 27–36 repeat. Otherwise the program continues execution with the first statement in sequence after the body of the loop (i.e., line 40).

Line 40 assigns the results of the average calculation to variable average. Lines 43–44 write a line of XHTML text in the document that displays the string "Class average is " followed by the value of variable average as an <h1> element in the browser.

Execute the script in a web browser by double clicking the XHTML document (from Windows Explorer). This script parses any user input as an integer. In the sample program execution in Fig. 5.5, the sum of the values entered (100, 88, 93, 55, 68, 77, 83, 95, 73 and 62) is 794. Although the treats all input as integers, the averaging calculation in the program does not produce an integer. Rather, the calculation produces a floating-point number (i.e., a number containing a decimal point). The average of the 10 integers input by the user in this example is 79.4.

Image

Software Engineering Observation 5.5

If the string passed to parseInt contains a floating-point numeric value, parseInt simply truncates the floating-point part. For example, the string “27.95” results in the integer 27, and the string “–123.45” results in the integer –123. If the string passed to parseInt is not a numeric value, parseInt returns NaN (not a number).

JavaScript actually represents all numbers as floating-point numbers in memory. Floating-point numbers often develop through division, as shown in this example. When we divide 10 by 3, the result is 3.3333333…, with the sequence of 3s repeating infinitely. The computer allocates only a fixed amount of space to hold such a value, so the stored floating-point value can be only an approximation.

5.7 Formulating Algorithms: Sentinel-Controlled Repetition

Let us generalize the class-average problem. Consider the following problem:

Develop a class-averaging program that will process an arbitrary number of grades each time the program is run.

In the first class-average example, the number of grades (10) was known in advance. In this example, no indication is given of how many grades the user will enter. The program must process an arbitrary number of grades. How can the program determine when to stop the input of grades? How will it know when to calculate and display the class average?

One way to solve this problem is to use a special value called a sentinel value (also called a signal value, a dummy value or a flag value) to indicate the end of data entry. The user types in grades until all legitimate grades have been entered. Then the user types the sentinel value to indicate that the last grade has been entered.

Clearly, one must choose a sentinel value that cannot be confused with an acceptable input value. –1 is an acceptable sentinel value for this problem because grades on a quiz are normally nonnegative integers from 0 to 100. Thus, an execution of the class-average program might process a stream of inputs such as 95, 96, 75, 74, 89 and –1. The program would compute and print the class average for the grades 95, 96, 75, 74 and 89 (–1 is the sentinel value, so it should not enter into the average calculation).

Figure 5.6 shows the JavaScript program and a sample execution. Although each grade is an integer, the averaging calculation is likely to produce a number with a decimal point (a real number).

Fig. 5.6 | Sentinel-controlled repetition to calculate a class average. (Part 1 of 2.)

Image

Fig. 5.6 | Sentinel-controlled repetition to calculate a class average. (Part 2 of 2.)

Image

In this example, we see that control statements may be stacked on top of one another (in sequence). The while statement (lines 31–45) is followed immediately by an if...else statement (lines 48–57) in sequence. Much of the code in this program is identical to the code in Fig. 5.5, so we concentrate in this example on the new features.

Line 21 initializes gradeCounter to 0, because no grades have been entered yet. Remember that the program uses sentinel-controlled repetition. To keep an accurate record of the number of grades entered, the script increments gradeCounter only after processing a valid grade value.

Note the block in the while loop in Fig. 5.6 (lines 32–45). Without the braces, the last three statements in the body of the loop would fall outside of the loop, causing the computer to interpret the code incorrectly, as follows:

while ( gradeValue != -1 )
   // add gradeValue to total
   total = total + gradeValue;

// add 1 to gradeCounter
gradeCounter = gradeCounter + 1;

// prompt for input and read grade from user
grade = window.prompt(
   "Enter Integer Grade, -1 to Quit:", "0" );

// convert grade from a string to an integer
gradeValue = parseInt( grade );

This interpretation would cause an infinite loop in the program if the user does not enter the sentinel -1 as the first input value in lines 25–26 (i.e., before the while statement).

Image

Common Programming Error 5.7

Omitting the braces that delineate a block can lead to logic errors such as infinite loops.

5.8 Formulating Algorithms: Nested Control Statements

Consider the following problem statement:

A college offers a course that prepares students for the state licensing exam for real estate brokers. Last year, several of the students who completed this course took the licensing exam. Naturally, the college wants to know how well its students performed. You have been asked to write a program to summarize the results. You have been given a list of these 10 students. Next to each name is written a 1 if the student passed the exam and a 2 if the student failed.

Your program should analyze the results of the exam as follows:

1. Input each test result (i.e., a 1 or a 2). Display the message “Enter result” on the screen each time the program requests another test result.

2. Count the number of test results of each type.

3. Display a summary of the test results indicating the number of students who passed and the number of students who failed.

4. If more than eight students passed the exam, print the message “Raise tuition.”

After reading the problem statement carefully, we make the following observations about the problem:

1. The program must process test results for 10 students. A counter-controlled loop will be used.

2. Each test result is a number—either a 1 or a 2. Each time the program reads a test result, the program must determine whether the number is a 1 or a 2. We test for a 1 in our algorithm. If the number is not a 1, we assume that it is a 2.

3. Two counters are used to keep track of the exam results—one to count the number of students who passed the exam and one to count the number of students who failed the exam.

After the program processes all the results, it must decide whether more than eight students passed the exam. The JavaScript program and two sample executions are shown in Fig. 5.7.

Fig. 5.7 | Examination-results calculation. (Part 1 of 2.)

Image

Fig. 5.7 | Examination-results calculation. (Part 2 of 2.)

Image

Lines 13–16 declare the variables used to process the examination results. Note that JavaScript allows variable initialization to be incorporated into declarations (passes is assigned 0, failures is assigned 0 and student is assigned 1). Some programs may require reinitialization at the beginning of each repetition; such reinitialization would normally occur in assignment statements.

The processing of the exam results occurs in the while statement in lines 19–29. Note that the if...else statement in lines 23–26 in the loop tests only whether the exam result was 1; it assumes that all other exam results are 2. Normally, you should validate the values input by the user (i.e., determine whether the values are correct).

5.9 Assignment Operators

JavaScript provides several assignment operators (called compound assignment operators) for abbreviating assignment expressions. For example, the statement

c = c + 3;

can be abbreviated with the addition assignment operator, +=, as

c += 3;

The += operator adds the value of the expression on the right of the operator to the value of the variable on the left of the operator and stores the result in the variable on the left of the operator. Any statement of the form

variable = variable operator expression;

where operator is one of the binary operators +, -, *, / or % (or others we’ll discuss later in the text), can be written in the form

variable operator = expression;

Thus, the assignment c += 3 adds 3 to c. Figure 5.8 shows the arithmetic assignment operators, sample expressions using these operators and explanations of the meaning of the operators.

Fig. 5.8 | Arithmetic assignment operators.

Image

Image

Performance Tip 5.1

Programmers can write programs that execute a bit faster when the arithmetic assignment operators are used, because the variable on the left side of the assignment does not have to be evaluated twice.

Image

Performance Tip 5.2

Many of the performance tips we mention in this text result in only nominal improvements, so you may be tempted to ignore them. Significant performance improvement often is realized when a supposedly nominal improvement is placed in a loop that may repeat a large number of times.

5.10 Increment and Decrement Operators

JavaScript provides the unary increment operator (++) and decrement operator (--) (summarized in Fig. 5.9). If a variable c is incremented by 1, the increment operator, ++, can be used rather than the expression c = c + 1 or c += 1. If an increment or decrement operator is placed before a variable, it is referred to as the preincrement or predecrement operator, respectively. If an increment or decrement operator is placed after a variable, it is referred to as the postincrement or postdecrement operator, respectively.

Fig. 5.9 | Increment and decrement operators.

Image

Image

Error-Prevention Tip 5.1

The predecrement and postdecrement JavaScript operators cause the W3C XHTML Validator to incorrectly report errors. The validator attempts to interpret the decrement operator as part of an XHTML comment tag (<!-- or -->). You can avoid this problem by using the subtraction assignment operator (-=) to subtract one from a variable. Note that the validator may report many more (nonexistent) errors once it improperly parses the decrement operator.

Preincrementing (or predecrementing) a variable causes the program to increment (decrement) the variable by 1, then use the new value of the variable in the expression in which it appears. Postincrementing (postdecrementing) the variable causes the program to use the current value of the variable in the expression in which it appears, then increment (decrement) the variable by 1.

The script in Fig. 5.10 demonstrates the difference between the preincrementing version and the postincrementing version of the ++ increment operator. Postincrementing the variable c causes it to be incremented after it is used in the document.writeln method call (line 18). Preincrementing the variable c causes it to be incremented before it is used in the document.writeln method call (line 25). The program displays the value of c before and after the ++ operator is used. The decrement operator (--) works similarly.

Fig. 5.10 | Preincrementing and postincrementing. (Part 1 of 2.)

Image

Fig. 5.10 | Preincrementing and postincrementing. (Part 2 of 2.)

Image

Image

Good Programming Practice 5.3

For readability, unary operators should be placed next to their operands, with no intervening spaces.

The three assignment statements in Fig. 5.7 (lines 24, 26 and 28, respectively),

passes = passes + 1;
failures = failures + 1;
student = student + 1;

can be written more concisely with assignment operators as

passes += 1;
failures += 1;
student += 1;

with preincrement operators as

++passes;
++failures;
++student;

or with postincrement operators as

passes++;
failures++;
student++;

It is important to note here that when incrementing or decrementing a variable in a statement by itself, the preincrement and postincrement forms have the same effect, and the predecrement and postdecrement forms have the same effect. It is only when a variable appears in the context of a larger expression that preincrementing the variable and post-incrementing the variable have different effects. Predecrementing and postdecrementing behave similarly.

Image

Common Programming Error 5.8

Attempting to use the increment or decrement operator on an expression other than aleft-hand-side expression —commonly called anlvalueis a syntax error. A left-hand-side expression is a variable or expression that can appear on the left side of an assignment operation. For example, writing ++(x + 1) is a syntax error, because (x + 1) is not a left-hand-side expression.

Figure 5.11 lists the precedence and associativity of the operators introduced to this point. The operators are shown top to bottom in decreasing order of precedence. The second column describes the associativity of the operators at each level of precedence. Notice that the conditional operator (?:), the unary operators increment (++) and decrement (--) and the assignment operators =, +=, -=, *=, /= and %= associate from right to left. All other operators in the operator precedence table (Fig. 5.11) associate from left to right. The third column names the groups of operators.

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

Image

5.11 Web Resources

www.deitel.com/javascript/

The Deitel JavaScript Resource Center contains links to some of the best JavaScript resources on the web. There you’ll find categorized links to JavaScript tutorials, tools, code generators, forums, books, libraries, frameworks and more. Be sure to visit the related Resource Centers on XHTML (www.deitel.com/xhtml/) and CSS 2.1 (www.deitel.com/css21/).

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

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