Control flow

Control flow is the order in which the JavaScript interpreter executes statements. If a script doesn't include statements that alter its flow, it's executed from beginning to end, one line at a time. Control structures are used to determine whether or not a set of statements are executed based on a defined set of criteria, execute a set of statements repeatedly, or interrupt a sequence of statements.

Conditional statements

Conditional statements determine whether code should be executed based on one or more conditions. A conditional statement executes the code it contains if the associated condition (or set of conditions) evaluates to true. Otherwise, the code is skipped.

ifelse

An if statement evaluates a condition inside the matched parentheses that follow. If the condition inside the parentheses evaluates to true, the statement or block statement that follows the matched parentheses is executed:

if ( true ) console.log( "True." );
> "True."

if ( true ) {
    const myString = "True.";
    console.log( myString );
}
> "True."

If the condition inside the parentheses evaluates to false, the statement that follows it is ignored:

if ( false ) console.log( "True." );

An else keyword immediately following an if statement and its conditionally-executed statement specifies the statement to be executed if the if condition evaluates to false:

if ( false ) console.log( "True." )''
else console.log( "False" );
> "False."

To chain multiple if statements together, you can make the conditionally-executed statement following else another if statement:

const myCondition = 2;
if ( myCondition === 5 ) console.log( "Five." );
else if ( myCondition === 2 ) console.log( "Two." );

We strongly recommend using block statement syntax following conditionals to improve readability, but else if clauses are often an exception to this:

if ( myCondition === 5 ) {
    console.log( "Five." );
} else if ( myCondition === 3 ) {
    console.log( "Three" );
} else {
    console.log( "Neither five nor three." );
}
> "Neither five nor three."

Ternary operator

if conditionally executes a statement. The ternary operator (more accurately but less commonly called the ternary conditional operator) is shorthand used to conditionally execute an expression. As the name implies, the ternary operator is the only JavaScript operator that uses three operands:

  • A condition to be evaluated, followed by a question mark (?).
  • The expression to execute if the condition evaluates to true, followed by a colon (:).
  • The expression to execute if the condition evaluates to false.

This is frequently used to conditionally set or pass a value:

const myFirstResult  = true  ? "First value." : "Second value.";
const mySecondResult = false ? "First value." : "Second value.";

myFirstResult;
> "First value."

mySecondResult;
> "Second value."

switchcase

Use the switch statement to compare the value of an expression to a list of potential values defined using one or more case keywords. This syntax is unusual because it comes from some of JavaScript's earliest design decisions. switchcase syntax uses the switch keyword, followed by an expression to be evaluated wrapped in parentheses, followed by a matched pair of curly braces. The body of the switch can contain case keywords, usually one or more, followed by an expression or value, followed by a colon (:).

When the interpreter reaches a case with a value matching the expression being evaluated in the parentheses following the switch keyword, it executes any statements that follow that case clause:

switch ( 2 + 2 === 4 ) {
  case false:
    console.log( "False." );
  case true:
    console.log( "True." );
}
> "True."

All statements following the matching case are executed, even if they're enclosed in a block statement.

switch ( 2 + 2 === 4 ) {
    case false:
    console.log( "False." );
  case true:
    let myVariable = "True.";
    console.log( myVariable );

}
> "True."

One pitfall of using switch…case is that, after a match is found, the JavaScript interpreter executes any statement that follows the matched case, even those within other case clauses. This is called "falling through" to the next case:

switch ( 2 + 2 === 7 ) {
    case false:
    console.log( "False." );
  case true:
    console.log( "True." );
}
> "False."
> "True."

To prevent fall-through, end each case with the break keyword, which immediately stops evaluation of the switch body:

switch ( 2 + 2 === 7 ) {
    case false:
    console.log( "False." );
    break;
  case true:
    console.log( "True." );
    break;
}
> "False."

If no case matches the conditional value, the switch selects the default clause if there is one:

switch ( 20 ) {
    case 5:
    console.log( "The value was five." );
    break;
  case 10:
    console.log( "The value was ten." );
    break;
  default:
    console.log( "The value was something unexpected." );
}
> "The value was something unexpected."

However, fall-through applies to default as well, potentially leading to unexpected results. To fix this, end your default statement with break, or place it last in the list of cases.

switch ( 20 ) {
  default:
    console.log( "The value was something unexpected." );
  case 10:
    console.log( "The value was ten." );
    break;
  case 5:
    console.log( "The value was five." );
    break;
}
> The value was something unexpected.
> The value was ten.

Because case clauses don't require a block statement for grouping multiple statements, case and default clauses don't create lexical scope by themselves: