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.[1] For example:
[1] 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.[2] The matching case is determined using the
=== identity operator, not the
== equality operator, so the expressions must
match without any type conversion.
[2] 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.