home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


JavaScript: The Definitive GuideJavaScript: The Definitive GuideSearch this book

6.5. switch

An if statement causes a branch in the flow of a program's execution. You can use multiple if statements, as in the previous section, to perform a multiway branch. However, this is not always the best solution, especially when all of the branches depend on the value of a single variable. In this case, it is wasteful to repeatedly check the value of the same variable in multiple if statements.

The switch statement (implemented in JavaScript 1.2 and standardized by ECMAScript v3) handles exactly this situation, and it does so more efficiently than repeated if statements. The JavaScript switch statement is quite similar to the switch statement in Java or C. The switch keyword is followed by an expression and a block of code, much like the if statement:

switch(expression) {
    statements
} 

However, the full syntax of a switch statement is more complex than this. Various locations in the block of code are labeled with the case keyword followed by a value and a colon. When a switch executes, it computes the value of expression and then looks for a case label that matches that value. If it finds one, it starts executing the block of code at the first statement following the case label. If it does not find a case label with a matching value, it starts execution at the first statement following a special-case default: label. Or, if there is no default: label, it skips the block of code altogether.

switch is a confusing statement to explain; its operation becomes much clearer with an example. The following switch statement is equivalent to the repeated if/else statements shown in the previous section:

switch(n) {
  case 1:                      // Start here if n == 1
    // Execute code block #1.
    break;                     // Stop here
  case 2:                      // Start here if n == 2
    // Execute code block #2.
    break;                     // Stop here
  case 3:                      // Start here if n == 3
    // Execute code block #3.
    break;                     // Stop here
  default:                     // If all else fails...
    // Execute code block #4.
    break;                     // stop here
} 

Note the break keyword used at the end of each case in the code above. The break statement, described later in this chapter, causes execution to jump to the end of a switch statement or loop. The case clauses in a switch statement specify only the starting point of the desired code; they do not specify any ending point. In the absence of break statements, a switch statement begins executing its block of code at the case label that matches the value of its expression and continues executing statements until it reaches the end of the block. On rare occasions, it is useful to write code like this that falls through from one case label to the next, but 99% of the time you should be careful to end every case within a switch with a break statement. (When using switch inside a function, however, you may use a return statement instead of a break statement. Both serve to terminate the switch statement and prevent execution from falling through to the next case.)

Here is a more realistic example of the switch statement; it converts a value to a string in a way that depends on the type of the value:

function convert(x) {
    switch(typeof x) {
      case 'number':            // Convert the number to a hexadecimal integer
        return x.toString(16);  
      case 'string':            // Return the string enclosed in quotes
        return '"' + x + '"';
      case 'boolean':           // Convert to TRUE or FALSE, in uppercase
        return x.toString().toUpperCase( );
      default:                  // Convert any other type in the usual way
        return x.toString( )
    }
} 

Note that in the two previous examples, the case keywords are followed by number and string literals. This is how the switch statement is most often used in practice, but note that the ECMAScript v3 standard allows each case to be followed by an arbitrary expression.[18] For example:

[18]This makes the JavaScript switch statement much different from the switch statement of C, C++, and Java. In those languages, the case expressions must be compile-time constants, they must evaluate to integers or other integral types, and they must all evaluate to the same type.

case 60*60*24:
case Math.PI:
case n+1:
case a[0]: 

The switch statement first evaluates the expression that follows the switch keyword, then evaluates the case expressions, in the order in which they appear, until it finds a value that matches.[19] The matching case is determined using the === identity operator, not the == equality operator, so the expressions must match without any type conversion.

[19]This means that the JavaScript switch statement is not nearly as efficient as the switch statement in C, C++, and Java. Since the case expressions in those languages are compile-time constants, they never need to be evaluated at runtime as they are in JavaScript. Furthermore, since the case expressions are integral values in C, C++, and Java, the switch statement can often be implemented using a highly efficient "jump table."

Note that it is not good programming practice to use case expressions that contain side effects such as function calls or assignments, because not all of the case expressions are evaluated each time the switch statement is executed. When side effects occur only sometimes, it can be difficult to understand and predict the correct behavior of your program. The safest course is simply to limit your case expressions to constant expressions.

As explained earlier, if none of the case expressions match the switch expression, the switch statement begins executing its body at the statement labeled default:. If there is no default: label, the switch statement skips its body altogether. Note that in the earlier examples, the default: label appears at the end of the switch body, following all the case labels. This is a logical and common place for it, but it can actually appear anywhere within the body of the statement.

The switch statement is implemented in JavaScript 1.2, but it does not fully conform to the ECMAScript specification. In JavaScript 1.2, case expressions must be literals or compile-time constants that do not involve any variables or method calls. Furthermore, although ECMAScript allows the switch and case expressions to be of any type, JavaScript 1.2 and JavaScript 1.3 require that the expressions evaluate to primitive numbers, strings, or boolean values.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.