JavaScript has flow control statements that can deal with options.
Although the var statement is allowed in the parameters of flow control statement and it appears that those variables would have scope local to the flow control statement's block ({stuff between the curly brackets}), they do not. Rather they have scope to the function the flow control statement is in or application/global scope.
//Instead of this: function myfun() { var n = 0; for (var i = 0; i < 3; i++) { n += i; } return i; //Proof that this i has function scope } //Try this instead: function myfun2() { var n = 0, i; for (i = 0; i < 3; i++) { n += i; } return i; //Proof that this i has function scope }
Many of the flow control statements are followed by either a single statement or a block of statements. Many errors can be avoided by simply using curly brackets even for a single statement.
//Instead of this: if (x) y = 3; //Try this instead: if (x) { y = 3 }
break [label];
Terminates the current loop, switch, or specified label. Processing would continue at the statement following the loop, swtich, or specified label.
continue [label];
...
label:
statementOrBlock
Restarts a while, do ... while, for, or label. Instead of restarting, processing could optionally continue at a specified label.
do
statementOrBlock
while (condition) ;
Executes the statement at least once and repeats until the condition is false.
for ([InitialExpression]; [condition]; [IncrementalExpression])
statementOrBlock
Here is simple code to do something 3 times:
var strReturn = "", i;
for (i=0; i<3; i++) {
strReturn += String(i);
}
//strReturn now contains "012"
The for statement is in essences a "function" that is often within other function so
it is common to declare the initial counter (usu. var i=0) for multiple for statements
within a function. EG:
function areArraysEqual (array1, array2) {
var temp = [], i;
if ( (!array1[0]) || (!array2[0]) ) { // If either is not an array
return false;
}
if (array1.length != array2.length) {
return false;
}
// Put all the elements from array1 into a "tagged" array
for (i = 0; i<array1.length; i++) {
key = (typeof array1[i]) + "~" + array1[i];
// Use "typeof" so a number 1 isn't equal to a string "1".
if (temp[key]) { temp[key]++; } else { temp[key] = 1; }
// temp[key] = # of occurrences of the value (so an element could appear multiple times)
}
// Go through array2 - if same tag missing in "tagged" array, not equal
for (i = 0; i<array2.length; i++) {
key = (typeof array2[i]) + "~" + array2[i];
if (temp[key]) {
if (temp[key] == 0) { return false; } else { temp[key]--; }
// Subtract to keep track of # of appearances in array2
} else { // Key didn't appear in array1, arrays are not equal.
return false;
}
}
// If we get to this point, then every generated key in array1 showed up the exact same
// number of times in array2, so the arrays are equal.
return true;
}
This will execute the statements for all the properties of the object.
for (variable in object)
statementOrBlock
EG: This function lists all the properties of an object.
function showProps(obj, objName) {
var result = "";
for (var i in obj) {
result += objName + "." + i + " = " + obj[i] + "\n";
}
return result;
}
EG: It is common to get the direct properties an object (as opposed to inherited).
for (name in object) {
if (object.hasOwnProperty(name)) {
alert(name+": "+object[name]);
}
}
This has three variations:
if (condition) statement1
if (condition)
statementOrBlock1
else
statementOrBlock2
(condition) ? TrueExpression : FalseExpression
EG: var myObj = document.getElementById ? document.getElementById("dog") : document.all.dog;
if...else statements are often chained together. EG: The next few
examples are equivalent. Usually, the more formatting is used, the more readable
it is. The third example has a few curly brackets thrown around the the single
statements.
if(condition){if(condition){statementOrBlockOrBlock}else
statementOrBlock;statementOrBlock;}else
if(condition){if(condition){statementOrBlock}else
statementOrBlock;statementOrBlock;}else
statementOrBlock;
if (condition){
if (condition){
statementOrBlocks
}else statementOrBlock
statementOrBlock;
}else if (condition){
if (condition){
statementOrBlocks
}else statementOrBlock
statementOrBlock;
}else statementOrBlock;
if (condition){
if (condition){
statementOrBlocks
}else{
statementOrBlock
}
statementOrBlock
}else{
if (condition){
if (condition){
statementOrBlocks
}else{
statementOrBlock
}
statementOrBlock
}else{
statementOrBlock
}
}
If you are doing a series like if ... else if ... else if ... else, then use this
syntax for legibility:
if (condition) {
...
} else if (condition) {
...
} else if (condition) {
...
} else if (condition) {
...
} else {
...
}
Provides a statement with an identifier that lets you refer to it elsewhere in your program.
label : statementOrBlock
switch (expression) {
case label1 :
statementList1
[break;]
case label2 :
statementList2
[break;]
...
default :
statementListn
}
If the optional break statement is used in each case, then this is just like the VB/VBS Select Case statement. Otherwise the switch statement checks each case label, until it hits a break or the end.
The label is an expression, i.e. it doesn't have to be a literal or a string.
This example returns common boolean equivalents as true, otherwise false:
switch(v){
case 1:
case "1":
case true:
case "t":
case "T":
case "true":
case "True":
case "y":
case "Y":
case "yes":
case "Yes":
return true;
break;
default:
return false;
}
Note the tabbing.
Throws a user-defined exception. The exception thrown can be a string, a number, a Boolean, an object, almost anything.
throw exceptionExpression
try {
statementA1
[throw exception]
statementA2
}
[catch (exception)
statementB
]
[finally
statementC
]
The catch block of statements only occurs if an exception was thrown (explicitly or
unexpectedly) in the try block. The statements in the
finally block process after the try and catch
blocks, whether or not an exception was thrown.
try ... catch statements can be nested but if an inner try
... catch statement lacks a catch block, then the outer
catch block is used for exceptions.
This example throws an object:
function UserException (message) {
this.message = message;
this.name = "UserException";
}
function getMonthName (mo) {
mo = mo - 1
var months=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
if (months[mo] != null) {
return months[mo];
} else {
myUserException = new UserException("InvalidMonthNo");
throw myUserException;
}
}
try {
monthName = getMonthName(myMonth);
}
catch (e) {
monthName="unknown";
logMyErrors(e.message,e.name) // pass exception object to an err handler
}
The catch block can also rethrow an exception so that the user's
browser gets to handle it.
while (expression)
statementOrBlock
May not execute the statement even once.
Extends the scope chain of a statement.
with (object) {
statementOrBlock
}
This with statement enables the Math object to be
assumed for the PI property and the cos() and sin()
methods.
var a, x, y, r = 10;
alert(PI); //undefined
with (Math) {
a = PI * r * r; //Now JS know PI is actually Math.Pi
x = r * cos(PI);
y = r * sin(PI/2);
}
Page Modified: (Hand noted: 2005-02-23 20:00:24Z) (Auto noted: 2008-10-17 20:21:23Z)