JavaScript – Conditionals

Conditional statements execute or skip other statements
depending on the value of a specified expression. These statements are
the decision points of your code, and they are also sometimes known as
“branches.” If you imagine a JavaScript interpreter following a path
through your code, the conditional statements are the places where the
code branches into two or more paths and the interpreter must choose
which path to follow.

The subsections below explain JavaScript’s basic conditional,
the if/else statement, and also
cover switch, a more complicated
multiway branch statement.

if

The if statement is the
fundamental control statement that allows JavaScript to make
decisions, or, more precisely, to execute statements conditionally.
This statement has two forms. The first is:

if (expression)
    statement

In this form, expression is
evaluated. If the resulting value is truthy,
statement is executed. If
expression is falsy,
statement is not executed. (See Boolean Values for a definition of truthy and falsy values.)
For example:

if (username == null)       // If username is null or undefined,
    username = "John Doe";  // define it

Or similarly:

// If username is null, undefined, false, 0, "", or NaN, give it a new value
if (!username) username = "John Doe";

Note that the parentheses around the
expression are a required part of the
syntax for the if
statement.

JavaScript syntax requires a single statement after the
if keyword and parenthesized
expression, but you can use a statement block to combine multiple
statements into one. So the if
statement might also look like this:

if (!address) {
    address = "";
    message = "Please specify a mailing address.";
}

The second form of the if
statement introduces an else
clause that is executed when expression
is false. Its syntax is:

if (expression)
      statement1
else
      statement2

This form of the statement executes
statement1 if
expression is truthy and executes
statement2 if
expression is falsy. For example:

if (n == 1) 
    console.log("You have 1 new message.");
else
    console.log("You have " + n + " new messages.");

When you have nested if
statements with else clauses,
some caution is required to ensure that the else clause goes with the appropriate
if statement. Consider the
following lines:

i = j = 1;
k = 2;
if (i == j)
    if (j == k)
        console.log("i equals k");
else
    console.log("i doesn't equal j");    // WRONG!!

In this example, the inner if statement forms the single statement
allowed by the syntax of the outer if statement. Unfortunately, it is not
clear (except from the hint given by the indentation) which if the else goes with. And in this example, the
indentation is wrong, because a JavaScript interpreter actually
interprets the previous example as:

if (i == j) {
    if (j == k)
        console.log("i equals k");
    else
        console.log("i doesn't equal j");    // OOPS!
}

The rule in JavaScript (as in most programming languages) is
that by default an else clause is
part of the nearest if statement.
To make this example less ambiguous and easier to read, understand,
maintain, and debug, you should use curly braces:

if (i == j) {
    if (j == k) {
        console.log("i equals k");
    }
}
else {  // What a difference the location of a curly brace makes!
    console.log("i doesn't equal j");
}

Although it is not the style used in this book, many
programmers make a habit of enclosing the bodies of if and else statements (as well as other compound
statements, such as while loops)
within curly braces, even when the body consists of only a single
statement. Doing so consistently can prevent the sort of problem
just shown.

else if

The if/else statement
evaluates an expression and executes one of two pieces of code,
depending on the outcome. But what about when you need to execute
one of many pieces of code? One way to do this is with an else if statement. else if is not really a JavaScript
statement, but simply a frequently used programming idiom that
results when repeated if/else
statements are used:

if (n == 1) {
    // Execute code block #1
}
else if (n == 2) {
    // Execute code block #2
}
else if (n == 3) {
    // Execute code block #3
}
else {
    // If all else fails, execute block #4
}

There is nothing special about this code. It is just a series
of if statements, where each
following if is part of the
else clause of the previous
statement. Using the else if
idiom is preferable to, and more legible than, writing these
statements out in their syntactically equivalent, fully nested
form:

if (n == 1) {
    // Execute code block #1
}
else {
    if (n == 2) {
        // Execute code block #2
    }
    else {
        if (n == 3) {
            // Execute code block #3
        }
        else {
            // If all else fails, execute block #4
        }
    }
}

switch

An if statement causes a
branch in the flow of a program’s execution, and you can use the
else if idiom to perform a
multiway branch. This is not the best solution, however, when all of
the branches depend on the value of the same expression. In this
case, it is wasteful to repeatedly evaluate that expression in
multiple if statements.

The switch statement
handles exactly this situation. The switch keyword is followed by an
expression in parentheses and a block of code in curly
braces:

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 an
expression and a colon. case is
like a labeled statement, except that instead of giving the labeled
statement a name, it associates an expression with the statement.
When a switch executes, it
computes the value of expression and then
looks for a case label whose
expression evaluates to the same value (where sameness is determined
by the === operator). If it finds
one, it starts executing the block of code at the statement labeled
by the case. If it does not find
a case with a matching value, it
looks for a statement labeled default:. If there is no default: label, the switch statement 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 the interpreter to jump to
the end (or “break out”) of the switch statement and continue with the
statement that follows it. 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 percent of the time you should be careful
to end every case 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 + '"';
      default:                  // Convert any other type in the usual way
        return String(x);
    }
}

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

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

Because not all of the case
expressions are evaluated each time the switch statement is executed, you should
avoid using case expressions that
contain side effects such as function calls or assignments. 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 examples above, 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.


[4] The fact that the case
expressions are evaluated at run-time makes the JavaScript
switch statement much
different from (and less efficient than) the switch statement of C, C++, and Java.
In those languages, the case
expressions must be compile-time constants of the same type, and
switch statements can often
compile down to highly efficient jump
tables
.

Comments are closed.