JavaScript has flow control statements that can deal with options. These statements consist primarily of 2 for branching (if and switch) and 3 for for looping (for, do ... while, and while).

Style

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

break [label];

Terminates the current loop, switch, or specified label. Processing would continue at the statement following the loop, swtich, or specified label.

continue

continue [label];
...
label:
    statementOrBlock

Interrupts the current loop or labelled loop, and starts the next iteration of the loop.

var i = 0;
while (i < 4) {
    i++;
    if (i === 2) {
        continue
    }
    alert(i);
    // Would alert 1, 3, 4
}

var j = 0, k = 0;
lbl1:
while (j < 6) {
    j++;
    lbl2:
    while (k < 4) {
        k++;
        if (k === 2) {
            continue lbl2;
        }
        alert(' k:' + k);
    }
    alert(' j:' + j);
}

do ... while

do
    statementOrBlock
while (condition) ;

Executes the statement at least once and repeats until the condition is false.

for

for ([InitialExpression]; [condition]; [IncrementalExpression])
    statementOrBlock

Like the while statement, the condition is checked before any looping (if any) is done.

Here is simple code to do something 3 times:

var strReturn = "";
for (var i = 0; i < 3; i++) {
   strReturn += String(i);
}
// strReturn now contains "012"

Looping through an array is very common:

var strReturn = "", arr = [1, 23, 456];
for (var i = 0; i < arr.length; i++) {
    strReturn += String(arr[i]);
}

// Do it faster by getting the length once:
for (var i = 0, ii = arr.length; i < ii; i++) {
   strReturn += String(arr[i]);
}

// Do it even faster variation uses the while loop:
var i = arr.length;
while (i--) {
    strReturn += String(arr[i]);
}

Faster variants via: Google Closure: How not to write JavaScript [http://www.sitepoint.com/google-closure-how-not-to-write-javascript/].

The for statement is in essence a "function" that is often within other function so it is common to initialize counter (usu. 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;
}

for ... in

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]);
    }
}

if ... else

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 {
    ...
}

label

Provides a statement with an identifier that lets you refer to it elsewhere in your program.

label :
    statementOrBlock

switch

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;
}

The switch statement is the only statement that violates the indentation convention of indenting the content between the curly brackets.

throw

Throws a user-defined exception. The exception thrown can be a string, a number, a Boolean, an object, almost anything.

throw exceptionExpression

It is possible to throw various Error objects, but that varies between JavaScript variants so you might as well throw your own object.

// ECMAScript:
errorObj = new Error([message]);

// Mozilla JavaScript:
errorObject = new Error([message[, fileName[, lineNumber]]]);

// Microsoft JScript:
errorObj = new Error([number[, description]]); //0 and '' by default

try ... catch

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. In other languages you can have multiple catch blocks to catch different kinds of errors, but with JavaScript you have one catch and you can identify the exception thrown by duck typing. If you omit catch blocks all together, then try to not omit the finally block --otherwise why did you bother to use the try block?

try ... catch statements can be nested but if an inner try ... catch statement lacks a catch block, then the outercatch 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

while (expression)
    statementOrBlock

May not execute the statement even once.

with

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);
}


GeorgeHernandez.comSome rights reserved