[ Team LiB ] Previous Section Next Section

4.6 Branching Execution Based on Conditions

NN 4, IE 4

4.6.1 Problem

You want your scripts to execute sections of code based on external values, such as Booleans, user entries in text boxes, or user choices from select elements.

4.6.2 Solution

Use the if, if/else, or switch flow control constructions to establish an execution path through a section of your scripts. When you need to perform a special section of script if one condition is met only, use the simple if construction with a conditional expression that tests for the condition:

if (condition) {
    // statements to execute if condition is true
}

To perform one branch under one condition and another branch for all other situations, use the if/else construction:

if (condition) {
    // statements to execute if condition is true
} else {
    // statements to execute if condition is false
}

You can be more explicit in the else clause by performing additional condition tests:

if (conditionA) {
    // statements to execute if conditionA is true
} else if (conditionB) {
    // statements to execute of conditionA is false and conditionB is true
} else {
    // statements to execute if both conditionA and conditionB are false
}

For multiple conditions, you should consider using the switch statement if the conditions are based on string or numeric value equivalency:

switch (expression) {
    case valueA:
        // statements to execute if expression evaluates to valueA
        break;
    case valueB:
        // statements to execute if expression evaluates to valueB
        break;
    ...
    default:
        // statements to execute if expression evaluates to no case value
}

The break statements in each of the case branches assure that the default branch (which is optional) does not also execute.

4.6.3 Discussion

A condition expression in the if and if/else constructions is an expression that evaluates to a Boolean true or false. Typically, such expressions use comparison operators (= =, = = =, !=, != =, <, <=, >, >=) to compare the relationship between two values. Most of the time, you are comparing a variable value against some constant or known value:

var theMonth = myDateObj.getMonth( );
if (theMonth =  = 1) {
    // zero-based value means the date is in February
    monLength = getLeapMonthLength(myDateObj);
} else {
    monLength = getMonthLength(theMonth);
}

JavaScript offers some additional shortcut evaluations for condition expressions. These shortcuts come in handy when you need to branch based on the existence of an object or property. Table 4-1 lists the conditions that automatically evaluate to true or false when placed inside the parentheses of a condition expression. For example, the existence of an object evaluates to true, which allows a construction such as the following to work:

if (myObj) {
    // myObj exists, so use it
}

Table 4-1. Condition expression equivalents

true

false

String has one or more characters

Empty string

Number other than zero

0

Nonnull value

null

Referenced object exists

Referenced object does not exist

Object property is defined and evaluates to a string of one or more characters or a nonzero number

Object property is undefined, or its value is an empty string or zero

When testing for the existence of an object property (including a property of the global window object), be sure to start the reference with the object, as in the following:

if (window.innerHeight) { ... }

But you also need to be careful when testing for the existence of a property if there is a chance that its value could be an empty string or zero. Such values force the conditional expression to evaluate to false, even though the property exists. Therefore, it is better to test for the data type of the property with the typeof operator. If you're not sure about the data type, test the data type against the undefined constant:

if (typeof myObj.myProperty != "undefined" ) {
    // myProperty exists and has a value of some kind assigned to it
}

If there is a chance that neither the object nor its property exists, you need to group together conditional expressions that test for the existence of both. Do this by testing for the object first, then the property. If the object does not exist, the expression short-circuits the test of the property:

if (myObj && typeof myObj.myProperty != "undefined") {
    // myObj exists, and so does myProperty
}

If you test for the property first, the test fails with a script error because the expression with the object fails unceremoniously.

JavaScript also provides a shortcut syntax that lets you avoid the curly braces for simple assignment statements that execute differently based on a condition. The syntax is as follows:

var myValue = (condition) ? value1 : value2;

If the condition evaluates to true, the righthand expression evaluates to the first value; otherwise, it evaluates to the second value. For example:

var backColor = (temperature > 100) ? "red" : "blue";

Several recipes in later chapters use this shortcut construction frequently, even to two levels deep. For example:

var backColor = (temperature > 100) ? "red" : ((temperature < 80) ? 
    "blue" : "yellow");

This shortcut expression is the same as the longer, more readable, but less elegant version:

var backColor ;
if (temperature > 100) {
    backColor = "red";
} else if (temperature < 80) {
    backColor = "blue";
} else {
    backColor = "yellow";
}

When you have lots of potential execution branches, and the triggers for the various branches are not conditional expressions per se, but rather the value of an expression, then the switch construction is the way to go. In the following example, a form contains a select element that lets a user choose a size for a product. Upon making that choice, an onchange event handler in the select element triggers a function that inserts the corresponding price for the size in a text box:

function setPrice(form) {
    var sizeList = form.sizePicker;
    var chosenItem = sizeList.options[sizeList.selectedIndex].value;
    switch (chosenItem) {
        case "small" :
            form.price.value = "44.95";
            break;
        case "medium" :
            form.price.value = "54.95";
            break;
        case "large" :
            form.price.value = "64.95";
            break;
        default:
             form.price.value = "Select size";
    }
}

If the switch expression always evaluates to one of the cases, you can omit the default branch, but while you are in development of the page, you might leave it there as a safety valve to alert you of possible errors if the expression should evaluate to an unexpected value.

4.6.4 See Also

Most of the recipes in Chapter 15 use the shortcut conditional statement to equalize disparate event models.

    [ Team LiB ] Previous Section Next Section