The flow-of-control in JavaScript programs is controlled by control statements, for example: if, switch, for and while. JavaScript also supports exceptions with try and catch.
This topic discusses control statements in alphabetical order: break, case, catch, continue, default, do, else, for, if, finally, label, return, Switch, throw, try, try...catch, try...finally, while, with.
label: for ( var i = 0; i < limit; i++ ) { if ( condition ) { break label; } } switch ( expression ) { case 1: Statements1; break; default: DefaultStatements; break; }
This keyword is used in, for loops, do loops, while loops and Switch statements. When a break statement is encountered in a loop, control is passed to the statement following the end of the inner-most loop that contains the break statement; unless the break statement is followed by the name of a label, in which case control passes to the statement governed by the label.
A break statement is usually placed at the end of each case in a Switch statement to prevent the interpreter "falling through" to the next case. When the interpreter encounters a break statement, it passes control to the statement that follows the inner-most enclosing Switch statement. If every case has a corresponding break, then at most one case's statements will be executed.
If the break statement is followed by a label name (see label) then when the break is encountered, control will pass to the statement marked with that label; this is useful, for example, for breaking out of deeply nested loops.
Example:
red: for ( x = 0; x < object.width; x++ ) { for ( y = 0; y < object.height; y++ ) { if ( color[x][y] == 0xFF0000 ) { break red; } } }
switch ( expression ) { case Value: Statements; break; default: DefaultStatements; break; }
This keyword is used in Switch statements. For each possible value that a Switch statement's expression may evaluate to, one case may be written, (but see default.) If a case's literal value (Value) matches the value of the Switch statement's expression, then that case's statements (Statements) are executed.
Normally a case's statements are terminated by a break statement which causes execution to pass to the end of the Switch statement.
See Switch for an example.
try { Statements; } catch( exception ) { ExceptionStatements; }
This keyword is used in try statements. If an exception occurs, then the ExceptionStatements in a matching catch block are executed.
Catch blocks come in two varieties, unqualified and qualified. An unqualified catch block has the form:
catch ( e ) { /* statements */ }
and a qualified catch block has the form:
catch ( e if e instanceOf RangeError ) { /* statements */ }
The possible exception types are:
EvalError -- the result of a failed eval() call.
RangeError -- a result that is out of range, example: an array index to an element that is not in the array.
TypeError -- an attempt to perform an operation on an object of an inappropriate type.
User defined exceptions -- exceptions that are objects of a user-defined type.
See try for an example. Also, see throw.
for ( var i = 0; i < limit; i++ ) { if ( condition ) { continue; } Statements; }
This keyword is used within the context of a for, while or do loop.
If a continue statement is encountered in a for loop, execution immediately passes to the third part of the for loop (normally where a counter is incremented or decremented), and then execution continues normally, that is, the middle part of the for loop (the conditional) is tested and if true, the body of the loop is executed.
If a continue statement is encountered in a while or do loop, execution immediately passes to the conditional, which is retested; the body of the loop will be executed if the conditional is still true.
See do for an example.
switch ( expression ) { case 1 : Statements1; break; default : DefaultStatements; break; }
This keyword is used in Switch statements. It is used instead of case to match anything that the Switch statement's expression has evaluated to. If no default is used, and none of the cases match, then the Switch statement will not execute anything and control will pass on to the following statement. If default is used, it must be the last case in the Switch statement. This is because each case is evaluated in order and since default matches any value, it will always be executed if the interpreter reaches it and any following cases would always be ignored. When the default case is encountered its DefaultStatements are executed. It is customary to end a default statement with a break.
See Switch for an example.
do { Statements; } while ( condition );
This keyword is used in conjunction with while to form a loop which is guaranteed to execute at least once.
The Statements in the braces following the do are executed once. If the while condition evaluates to true, execution passes back to the do and the whole process repeats. If the while loop's conditional ever becomes false, execution continues from the statement following the while statement.
Example:
var x = 0; do { x += 5; if ( x == 50 ) continue; debug( x ); } while ( x < 100 );
The example outputs 5, 10, 15, ..., 45, 55, 60, 65, ..., 95.
See also continue and break.
if ( condition ) { Statements; } else { ElseStatements; }
The else keyword is used in conjunction with if. See if for details.
for ( i = 0; i < limit; i++ ) { Statements; }
This keyword is used to create a loop that executes a fixed number of times.
The for statement is broken into parts as follows: the keyword for, an opening parentheses, zero or more statements (the first part), a semi-colon, a conditional expression (the second part), a semi-colon, zero or more statements (the third part), a closing parentheses and finally a statement or block that is governed by the for loop.
The first part of the for statement is typically used to initialize (and possibly declare) the variable used in the conditional in the second part of the for loop statement. This part is executed once before the loop begins. This part may be empty.
The second part contains a conditional expression. The expression is evaluated before each iteration of the loop (including before the first iteration). If this expression evaluates to false, the statement or block governed by the for loop is not executed and control passes to the statement that follows. If the condition is never true, the statement or block governed by the for loop will never be executed. If the condition expression is true, the statement or block governed by the for loop is executed and then the third part of the for statement is executed, before control is passed back to the conditional expression with the whole process being repeated. This part should not be empty.
The third part contains statements which must be executed at the end of every iteration of the loop. This part is typically used to increment a variable that was initialized in the first part and whose value is tested in the second part. This part may be empty.
Example:
var a = [ "a", "b", "c", "d", "e" ]; for( var i = 0; i < a.length; i++ ) { debug( a[ i ] ); }
See also continue and break.
if ( expression1 ) { // statements1 } else { // elsestatements } if ( expression1 ) { // statements1 } else if ( expression2 ) { // statements2 } // else if ... } else { // elsestatementsN }
An if statement provides a two-way branch. A multi-way branch is achieved using else ifs. (See also Switch.)
If the first expression, expression1, is true, then the statements governed by that expression (statements1) will be executed, after which control will pass to the statement following the if block.
If expression1 is false, control passes to the else statement. If the else has no following if, the else statements (elsestatements) are executed, after which control will pass to the statement following the if block. If the else has a following if, then step 1 or step 2 (this step) is repeated for that if statement depending on whether its expression is true or false.
try { Statements; } finally { finalStatements; }
A "finally" block is a block of code that is executed after the governing try block. If no exceptions occur within the try block, control will pass to the finally block after the last statement in the try block has been executed. If an exception occurs within the try block, control is passed immediately to the finally block.
See try...finally for an example.
labelname: Statement;
Statements may be labelled; the syntax is labelname followed by a colon, followed by the Statement. The labelname is any valid (unique) identifier.
See break for an example.
return optExpression;
A return statement may occur anywhere within a function, including member functions, but not within constructors. When a return statement is encountered, control leaves the function immediately and execution resumes at the statement following the call that invoked the function. If the return statement is followed by an expression (optExpression) the value of the expression is returned to the caller.
Example:
function inRange( v, min, max ) { if ( v >= min && v <= max ) { return true; } else { return false; } }
switch( expression ) { case Value : Statements; break; default : DefaultStatements; break; }
A switch statement provides a multi-way branch. The expression is evaluated once, then each case is checked in order to find one with a Value that matches the value of the expression. If a match is made, the statements of the matching case are executed, after which control passes to the statement following the switch block. If no matching case is found and there is a default case, the DefaultStatements are executed, after which control passes to the statement following the switch block. If there is no matching case and no default, no statements within the switch block are executed and control passes to the statement following the switch block.
Note that if a default is used it must be come after all the cases; this is because once default is encountered it is treated as a matching case regardless of what follows.
Every case and the default (if used) should have a break as their last statement. If break is not present, control will "drop through" to the following statements, which is not usually the desired behavior.
The expression may be any arbitrary JavaScript expression that evaluates to an object that can be strictly compared. For example, an expression that evaluates to a Boolean, Date, Number or String value.
Example:
switch( expr ) { case 1: doActionOne(); break; case "two": doActionTwo(); break; case 3: doActionThree(); case 4: doActionFour(); break; default: doDefaultAction(); break; }
In the example, if expr has the value 1, the doActionOne() function will be called. But if expr has the value 3, both doActionThree() and doActionFour() will be called because case 3 does not have a break statement and execution "falls through" to case 4. If expr is not 1, "two", 3 or 4 then the default case will be matched and doDefaultAction() will be executed.
try { Statements; throw "an exception"; } catch ( e ) { if ( e == "an exception" ) { ExceptionStatements; } else { OtherExceptionStatements } }
The throw keyword is used to raise user-defined exceptions.
Example:
function monthToName( i ) { var IndexToMonth = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; if ( i < 0 || i > 11 ) { throw "month number out of range"; } else { return IndexToMonth[ i ]; } }
It is also possible to define a user-defined exception class and throw an object of that type, example:
throw new AUserDefinedException( "month number out of range" );
See also try.
try { Statements; } catch ( e ) { } try { Statements; } finally { }
The try keyword is used to identify a statement block for which exceptions will be caught. There are two kinds of try block, try...catch and try...finally.
If an exception occurs within a try...catch block, control is passed to the first catch block. If that catch block does not accept the exception, control is passed on to the next catch block (if any) and so on, until there are no more catch blocks, in which case the exception is passed up the call chain until an enclosing catch block is found to accept it or if none accept it, the program will terminate.
Catch blocks come in two varieties, unqualified and qualified. An unqualified catch block has the form:
catch ( e ) { /* statements */ }
and a qualified catch block has the form:
catch ( e if e instanceOf RangeError ) { /* statements */ }
See catch for details of the qualifiers.
If an exception occurs within a try...finally block, control is passed to the finally block. This is useful if you want to ensure that something happens at the end of the block, no matter what.
Examples:
try { file = new File; file.open( filename ); process( file ); } finally { file.close(); }
In this example, the file is always closed, even if an exception occurred.
try { var a = monthToName( 11 ); var b = monthToName( 2 ); } catch ( e ) { if ( e == "month number out of range" ) { debug( "Code error: " + e ); } else { throw e; } }
In this example, the monthToName() function is called to set two variables. If the function fails, it throws an exception rather than returns an error value, so no explicit check for an error value is necessary. If one of the function calls failed debug() is called; otherwise the exception is re-thrown so that it can be handled at a higher level. (See throw for the definition of monthToName().)
while ( condition ) { Statements; }
This keyword is used to repeat a block of code zero or more times. When the while statement is encountered the condition is evaluated. If the condition is true, the Statements in the while block are executed; otherwise control passes to the statement following the while block. If the condition is true, after the Statements have been executed, the condition is again evaluated and the whole process repeats.
Example:
var i = 10; while ( i > 0 ) { debug( i ); i--; }
See also continue and break.
with ( QualifyingName ) { Statements; }
This keyword is used to indicate that any unqualified names in the Statements should be qualified by QualifyingName.
Example:
// Without with debug( Math.abs( -4 ) ); debug( Math.pow( 2, 3 ) ); debug( Math.random() ); // With with with ( Math ) { debug( abs( -4 ) ); debug( pow( 2, 3 ) ); debug( random() ); }
If multiple qualifying names are required, with statements can be nested.
Forcing the interpreter to do the lookup may be slower than using the fully qualified names.