The purpose of this series of lessons is to teach you how to program in JavaScript. The goal is to provide a programming tutorial that will be accessible to persons with no programming experience and will be equally useful to persons who already have programming experience using JavaScript or some other language.
Although you don't hear too much about it these days, programming instructors used to make a big deal about sequence, selection, and loop. (That was back when there wasn't much else to make a big deal about.) Programming these days involves so many new and more complex abstract concepts that these three have been relegated to the appendix in many books on computer programming.
The concept here is that the statements in a script are executed in sequence until a point is reached where it is necessary to either select a fork in the road, or loop and repeat the execution of a given set of statements more than once.
I recall one Pascal programming book using an analogy something like:
This lesson will be primarily concerned with learning about the flow
of control in JavaScript.
The following table is a partial list of the statements supported by
JavaScript for controlling the logical flow of the script. Some additional
statements will be presented in conjunction with the study of objects.
| Statement | Type |
| if-else | selection |
| switch-case | selection |
| for | loop |
| while | loop |
| do-while | loop |
| break | miscellaneous |
| continue | miscellaneous |
| label | miscellaneous |
| return | miscellaneous |
JavaScript supports two conditional statements:
if(conditional expression) statement or compound statement; else //optional statement or compound statement; //optional |
A compound statement is one or more individual statements enclosed in curly braces {} and treated as a group. This is often called a block in some languages.
The following sample script illustrates the behavior of the if-else
statement.
<!-- File Js00000140.htm
Copyright 1998, R.G.Baldwin
This JavaScript script is designed to illustrate the
use of the if-else statement.
The output from running this script is:
x is less than y
Second statement in compound statement
if branch, x is less than y
else branch, x is not greater than y
Done.
-------------------------------------------------------------------->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
x = 5; y = 6; z = 7;
<!-- if without an else, compound statement -->
if(x<y){
document.write("x is less than y<BR>");
document.write("Second statement in compound statement<BR>");
}//end compound statement for if
<!-- if with an else, not a compound statement -->
if(x < y)
document.write("if branch, x is less than y<BR>")
else
document.write("else branch, x is not less than y<BR>");
<!-- another if with an else -->
if(x > y)
document.write("if branch, x is greater than y<BR>");
else
document.write("else branch, x is not greater than y<BR>");
// End hiding -->
</SCRIPT>
</HEAD>
<BODY>
<P> Done.
</BODY>
</HTML>
|
| The condition can be any JavaScript expression that evaluates to true or false. The statements to be executed can be any JavaScript statements, including further nested if statements. If you want to use more than one statement after an if or else statement, you must enclose the statements in curly braces, {}. |
switch(expression){
case constant:
//sequence of optional statements
break; //optional
case constant:
//sequence of optional statements
break; //optional
.
.
.
default //optional
//sequence of optional statements
}
|
In JavaScript, the constant can be of numeric, string, or boolean type. In the case of boolean, it is similar to an if-else statement.
Because of accuracy considerations, you should probably avoid using numeric values having fractional parts that have been previously calculated for matching purposes. A very small difference in two calculated values could prevent a match.
Execution of statements continues until the optional break is encountered. When break is encountered, execution of the switch statement is terminated and control is passed to the next statement following the switch statement.
If no match is found and the optional default keyword along with a sequence of optional statements has been provided, those statements will be executed.
Switch statements can be nested as illustrated in the follow script. This script also illustrates what can happen if you forget to include the break statement. Note the line of output from this script that states that 8matches 9. This is the result of neglecting to include the break where appropriate and two statements were executed instead of just the one that should have been executed.
Note that it is not necessary to include multiple statements inside
of curly braces {} to cause multiple statements to be executed inside of
a switch statement.
<!-- File Js00000150.htm
Copyright 1998, R.G.Baldwin
This JavaScript script is designed to illustrate the
use of the unlabeled switch-case statement.
The output from running this script is:
5 matches 5
No match found for 3
cat matches cat
No match found for pig
true matches true
false matches false
8matches 8
8matches 9
Done.
-------------------------------------------------------------------->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
<!-- switch using numeric constants with a match -->
x = 5;
switch(x){
case 4: document.write(x + " matches 4");break
case 5: document.write(x + " matches 5");break
case 6: document.write(x + " matches 6");break
default: document.write("No match found for " + x);
}//end switch statement
document.write("<BR>");
<!-- switch using numeric constants without a match -->
x = 3;
switch(x){
case 4: document.write(x + " matches 4");break
case 5: document.write(x + " matches 5");break
case 6: document.write(x + " matches 6");break
default: document.write("No match found for " + x);
}//end switch statement
document.write("<BR>");
<!-- switch using string constants with a match -->
x = "cat";
switch(x){
case "dog": document.write(x + " matches dog");break
case "cat": document.write(x + " matches cat");break
case "rat": document.write(x + " matches rat");break
default: document.write("No match found for " + x);
}//end switch statement
document.write("<BR>");
<!-- switch using string constants without a match -->
x = "pig";
switch(x){
case "dog": document.write(x + " matches dog");break
case "cat": document.write(x + " matches cat");break
case "rat": document.write(x + " matches rat");break
default: document.write("No match found for " + x);
}//end switch statement
document.write("<BR>");
<!-- switch using boolean constants -->
x = "true";
switch(x){
case "true": document.write(x + " matches true");break
case "false": document.write(x + " matches false");break
}//end switch statement
document.write("<BR>");
<!-- another switch using boolean constants and nesting-->
x = "false", y = 8;
switch(x){
case "true":
document.write(x + " matches true<BR>");//no break here
switch(y){
case 8: document.write(y + "matches 8<BR>");//no break
case 9: document.write(y + "matches 9<BR>");
}//end nested switch statement
case "false":
document.write(x + " matches false<BR>");//no break here
switch(y){
case 8: document.write(y + "matches 8<BR>");//no break
case 9: document.write(y + "matches 9<BR>");
}//end nested switch statement
}//end switch statement
document.write("<BR>");
// End hiding -->
</SCRIPT>
</HEAD>
<BODY>
<P> Done.
</BODY>
</HTML>
|
A while statement executes its statements as long as a specified condition evaluates to true. It is probably the most straightforward of the three types of loops listed above.
The general syntax of a while statement is as follows
while (conditional expression) statement or compound statement; |
As with all loop statements, you must be careful to make certain that the conditional expression eventually evaluates to false. Otherwise, control will be trapped inside the while statement in what is commonly called an infinite loop.
The while statement is used to form an entry condition loop. The significance of an entry condition loop is that the conditional expression is tested before the statements in the body of the loop are executed. If it tests false initially, the statements in the loop will not be executed.
The following script illustrates the use of a simple while loop. This script initializes the value of a counter to 4 and then loops while the value of the counter is greater than 0.
During each pass through the loop (commonly called an iteration), a
decrement instruction is used to subtract one from the counter. The
value of the counter is tested at the beginning of each iteration.
When the value of the counter reaches zero, control is passed to the next
instruction following the loop. In this case, there aren't any more
instructions, so the script simply terminates
<!-- File Js00000160.htm
Copyright 1998, R.G.Baldwin
This JavaScript script is designed to illustrate the
use of the while loop statement.
The output from running this script is:
cnt = 4
cnt = 3
cnt = 2
cnt = 1
Done.
-------------------------------------------------------------------->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
cnt = 4;//initialize a counter
while(cnt > 0){//begin while loop
//display value of counter
document.write("cnt = " + cnt + "<BR>");
--cnt;//decrement counter
}//end while loop
// End hiding -->
</SCRIPT>
</HEAD>
<BODY>
<P> Done.
</BODY>
</HTML>
|
This script uses a counter named oCnt to control the outer loop and a counter named iCnt to control the inner loop. oCnt is initialized to a value of 4, and the outer loop is designed to loop for as long as the value of this counter remains greater than zero. The value of the counter is decremented by one at the end of each iteration of the outer loop.
The counter for the inner loop named iCnt is initialized to a value of 5 inside the outer loop. Then an inner loop is executed that continues to loop for as long as the value of this counter remains greater than zero. The counter for the inner loop is decremented by one at the end of each iteration of the inner loop.
Perhaps the most important thing to notice is that for every iteration of the outer loop, the inner loop iterates through its full range of iterations.
As you can see, the output from this script forms a sort of a rectangular
array with the value of oCnt indicating the row number and the value
of iCnt indicating a column number. In fact, nested while
loops of this sort are often used to process two-dimensional arrays (arrays
will be covered in a subsequent lesson).
<!-- File Js00000170.htm
Copyright 1998, R.G.Baldwin
This JavaScript script is designed to illustrate the
use of nested while loops.
The output from running this script is:
oCnt = 4 -- iCnt = 5 iCnt = 4 iCnt = 3 iCnt = 2 iCnt = 1
oCnt = 3 -- iCnt = 5 iCnt = 4 iCnt = 3 iCnt = 2 iCnt = 1
oCnt = 2 -- iCnt = 5 iCnt = 4 iCnt = 3 iCnt = 2 iCnt = 1
oCnt = 1 -- iCnt = 5 iCnt = 4 iCnt = 3 iCnt = 2 iCnt = 1
Done.
-------------------------------------------------------------------->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
oCnt = 4;//initialize a counter
while(oCnt > 0){//begin outer loop
//display value of oCnt
document.write("<BR>oCnt = " + oCnt + " -- ");
iCnt = 5;//initialize another counter
while(iCnt > 0){//begin inner loop
document.write("iCnt = " + iCnt + " ");
iCnt--;//decrement iCnt
}//end inner loop
--oCnt;//decrement counter
}//end outer loop
// End hiding -->
</SCRIPT>
</HEAD>
<BODY>
<P> Done.
</BODY>
</HTML>
|
do {
statements
} while (conditional expression);
|
All loop structures in JavaScript can be nested inside of other statements, including other loop structures of the same or a different type.
The following script illustrates the use of a simple do-while loop structure. This script is designed to illustrate the special quality of this structure that causes the statements inside the body of the loop to be executed once even if the conditional test fails the first time.
The script contains two identical do-while structures. The only difference between the two is the initial value of a counter that is used in the conditional test. Each structure iterates for as long as the value of the counter remains greater than zero.
In the second structure, the value of the counter is initially zero.
Therefore, the test fails the first time it is made and the loop terminates
the first time the test is made. Because the statements inside the
loop occur before the test is made, those statements are executed once.
<!-- File Js00000180.htm
Copyright 1998, R.G.Baldwin
This JavaScript script is designed to illustrate the
use of the do-while loop statement.
The output from running this script is:
cnt = 4
cnt = 3
cnt = 2
cnt = 1
Force false condition initially
cnt = 0
Done.
-------------------------------------------------------------------->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
cnt = 4;//initialize a counter
do{//begin do-while loop
//display value of counter
document.write("cnt = " + cnt + "<BR>");
--cnt;//decrement counter
}while(cnt > 0)//end while loop
document.write("<BR>Force false condition initially<BR>");
cnt = 0;//initialize a counter
do{//begin do-while loop
//display value of counter
document.write("cnt = " + cnt + "<BR>");
--cnt;//decrement counter
}while(cnt > 0)//end while loop
// End hiding -->
</SCRIPT>
</HEAD>
<BODY>
<P> Done.
</BODY>
</HTML>
|
A for loop iterates until a specified condition evaluates to
false. The heart of a for loop consists of three clauses separated
by semicolons as shown below.
for (first clause; second clause; third clause) simple or compound statement |
In other languages, the comma operator guarantees that its left operand will be executed before its right operand, and presumably this is also true in JavaScript, although I haven't been able to find that stated anywhere.
The expressions in the first clause are executed only once, at the beginning of the loop. Any legal expression(s) may be contained in the first clause, but typically the first clause is used for initialization.
Note that variables can also be declared and initialized in the first clause. (For those of you who have programmed in Java or C++, note that declaring variables in the first clause in JavaScript doesn't restrict the scope of those variables as it does in Java and C++.)
The second clause consists of a single expression which must eventually evaluate to false to cause the loop to terminate.
Typically relational expressions or relational and logical expressions are used in the second clause.
The value of the second clause is tested when the statement first
begins execution, and at the beginning of each iteration thereafter.
Therefore, the for loop is an entry condition loop.
| Contrary to some current (May 98) Netscape documentation, although the third clause appears physically at the top of the loop, it isn't executed until the statements in the body of the loop have completed execution. This is demonstrated in the sample program that follows. |
Multiple expressions can appear in the third clause, separated by the comma operator. If variables are updated in the third clause and used in the body of the loop, it is important to understand that they do not get updated until the execution of the body is completed.
The following script illustrates the use of a for loop. This script declares and initializes two variables named x and y in the first clause of the for loop. The variable named x is the control variable for the loop, and the loop continues to iterate for as long as the value of x is greater than zero. The variable y is used simply to illustrate the update behavior of the loop.
Both variables are updated in the third clause of the loop by decrementing them by one. Both variables are displayed in the body of the loop.
An important point to note is that the two variables are initialized to values of 3 and 4 and they still have that value the first time their values are displayed in the body of the loop, even though they are decremented in the third clause. This demonstrates that even though the update code is physically written at the top of the loop structure, the actual update isn't executed until the code in the body of the loop has been executed.
Again, for the benefit of Java and C++ programmers, the values of the
two variables are also displayed after the loop has terminated which is
different behavior than in Java and C++.
<!-- File Js00000190.htm
Copyright 1998, R.G.Baldwin
This JavaScript script is designed to illustrate the
use of a for loop.
The output from running this script is:
Inside loop: x, y = 3, 4
Inside loop: x, y = 2, 3
Inside loop: x, y = 1, 2
Outside loop: x, y = 0, 1
Done.
-------------------------------------------------------------------->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
for(x=3,y=4; x > 0; x--,y--){
document.write("Inside loop: ");
document.write("x, y = " + x + ", " + y + "<BR>");
}//end for loop
document.write("Outside loop: ");
document.write("x, y = " + x + ", " + y + "<BR>");
// End hiding -->
</SCRIPT>
</HEAD>
<BODY>
<P> Done.
</BODY>
</HTML>
|
The update of the two variables is embedded in the body of the loop
(at the end) and the third clause is also left blank. The output
is identical to that of the previous script, further reinforcing my earlier
claims as to when the statements in the update clause of a for loop
are executed.
<!-- File Js00000200.htm
Copyright 1998, R.G.Baldwin
This JavaScript script is designed to illustrate the
use of a for loop with empty first and third clauses.
The output from running this script is:
Inside loop: x, y = 3, 4
Inside loop: x, y = 2, 3
Inside loop: x, y = 1, 2
Outside loop: x, y = 0, 1
Done.
-------------------------------------------------------------------->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
x=3, y=4;
for( ; x > 0; ){
document.write("Inside loop: ");
document.write("x, y = " + x + ", " + y + "<BR>");
x--;
y--;
}//end for loop
document.write("Outside loop: ");
document.write("x, y = " + x + ", " + y + "<BR>");
// End hiding -->
</SCRIPT>
</HEAD>
<BODY>
<P> Done.
</BODY>
</HTML>
|
Another area where semicolons are required is in the writing of event
handlers, a topic that will be covered in a subsequent lesson. In
that case, you sometimes don't have any choice but to put two or more statements
on the same line which in turn requires the use of semicolons.
<!-- File Js00000210.htm
Copyright 1998, R.G.Baldwin
This JavaScript script is designed to illustrate that the
semicolon is required in JavaScript only to separate two statements
on the same line and as separators in a for loop.
The output from running this script is:
Inside loop: x, y = 3, 4
Inside loop: x, y = 2, 3
Inside loop: x, y = 1, 2
Outside loop: x, y = 0, 1
Done.
-------------------------------------------------------------------->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
x=3, y=4
for( ;x > 0; ){
document.write("Inside loop: ")
document.write("x, y = " + x + ", " + y + "<BR>")
x--; y--//note the semicolon separator
}//end for loop
document.write("Outside loop: ")
document.write("x, y = " + x + ", " + y + "<BR>")
// End hiding -->
</SCRIPT>
</HEAD>
<BODY>
<P> Done.
</BODY>
</HTML>
|
In my opinion, because there is a good possibility that you might like to also learn to program using Java someday, you should become accustomed to the placement of a semicolon to terminate each statement by using that programming style in JavaScript. It is easier to form good habits in the beginning than to break bad habits later on. Therefore, unless I forget to do so, you will see semicolons to terminate all of the statements in my JavaScript scripts.
The previous discussions on loops stated that the various loops continue to iterate for as long as some particular condition is true. That was only half the truth. In fact, it is possible to modify that behavior by making use of break and continue.
In a nutshell, break can be used to cause a loop to terminate prematurely. continue can be used to cause a particular iteration of a loop to terminate prematurely so that the next iteration begins immediately.
In addition, both break and continue can be used with
a label to provide even more complex behavior. This capability
mimics a capability that is also available in Java. I am a very experienced
Java programmer and I rarely find the need to use labeled break
and continue statements. Therefore, I will discuss the unlabeled
versions first followed by a brief discussion of the labeled versions.
When break is encountered in a loop, it causes control to be passed to the next statement outside the innermost enclosing loop. Loops can also be nested inside other loops and an unlabeled break statement only impacts the loop statement in which it appears.
The continue statement cannot be used in a switch statement. It is confined to loops.
When an unlabeled continue statement is encountered in a loop, it causes the current iteration to be terminated and the next iteration to begin.
The following sample script illustrates the use of an unlabeled break in a for loop. You might note that this is a modification of a script that was discussed earlier.
In this version, an if statement was inserted in the body of
the loop that causes the loop to break when the value of the variable
named y is equal to 3. As a result, even though the loop is
designed to iterate until the value of the control variable x reaches
zero (as in the sample script discussed earlier), the countdown terminates
early because of the break. When x is displayed after
the loop terminates, it has a value of 1 so it was never allowed to reach
zero as in the previous sample script.
<!-- File Js00000220.htm
Copyright 1998, R.G.Baldwin
This script is designed to illustrate the use of an unlabeled
break in a for loop.
The output from running this script is:
Inside loop: x, y = 4, 5
Inside loop: x, y = 3, 4
Inside loop: x, y = 2, 3
Outside loop: x, y = 1, 2
Done.
-------------------------------------------------------------------->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
for(x=4,y=5; x > 0; x--,y--){
if(y==3) break;
document.write("Inside loop: ");
document.write("x, y = " + x + ", " + y + "<BR>");
}//end for loop
document.write("Outside loop: ");
document.write("x, y = " + x + ", " + y + "<BR>");
// End hiding -->
</SCRIPT>
</HEAD>
<BODY>
<P> Done.
</BODY>
</HTML>
|
Inside loop: x, y = 2, 3
This is because the continue statement caused the iteration that
would have produced that output to be terminated prematurely and the next
iteration to begin immediately following the continue. As
a result, the document.write(...) statement in the body of the loop
wasn't executed during that iteration and this line of output wasn't produced.
<!-- File Js00000230.htm
Copyright 1998, R.G.Baldwin
This script is designed to illustrate the use of an unlabeled
continue in a for loop.
The output from running this script is:
Inside loop: x, y = 4, 5
Inside loop: x, y = 3, 4
Inside loop: x, y = 1, 2
Outside loop: x, y = 0, 1
Done.
-------------------------------------------------------------------->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
for(x=4,y=5; x > 0; x--,y--){
if(y==3) continue;
document.write("Inside loop: ");
document.write("x, y = " + x + ", " + y + "<BR>");
}//end for loop
document.write("Outside loop: ");
document.write("x, y = " + x + ", " + y + "<BR>");
// End hiding -->
</SCRIPT>
</HEAD>
<BODY>
<P> Done.
</BODY>
</HTML>
|
The general syntax of a labeled statement is as follows:
| label : statement |
Basically, a label can be used with break to cause control to break out of any labeled compound statement as illustrated in the following sample script.
This script contains two labeled compound statements that are essentially identical. However, a test is performed inside of each, and if the result if the test is true, a labeled break is executed on that compound statement.
The demonstration is designed to cause the test to be true in the first
compound statement and false in the second compound statement. As
a result, when control breaks out of the first compound statement, the
document.write() statement is skipped as indicated one line of missing
output in the comments at the beginning of the script.
<!-- File Js00000240.htm
Copyright 1998, R.G.Baldwin
This script is designed to illustrate the use of a labeled break
in a compound statement.
The output from running this script is:
Enter first compound statement
Out of first compound statement
Enter second compound statement
Still in second compound statement
Out of second compound statement
Done.
-------------------------------------------------------------------->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
document.write("Enter first compound statement<BR>");
aLabel:{//begin compound statement
myVar = 5;
if(myVar == 5)break aLabel;
document.write("Still in first compound statement<BR>");
}//end compound statement
document.write("Out of first compound statement<BR>");
document.write("<BR>Enter second compound statement<BR>");
bLabel:{//begin compound statement
myVar = 6;
if(myVar == 5)break bLabel;
document.write("Still in second compound statement<BR>");
}//end compound statement
document.write("Out of second compound statement<BR>");
// End hiding -->
</SCRIPT>
</HEAD>
<BODY>
<P> Done.
</BODY>
</HTML>
|
return may appear any number of times in a function, either with, or without an expression following it. If return is followed by an expression, that expression will be evaluated and the resulting value will be returned to the calling code. If return is not followed by an expression, nothing useful will be returned.
The first time that return is encountered in a function, control is transferred back to the code that invoked the function in the first place. This is illustrated in the following sample script.
This script contains a function named myFunction() that contains a return statement to prematurely terminate the function if the value of the incoming parameter is 5. When the function is not prematurely terminated, an output statement displays the text "Still in myFunction". However, when the return statement is executed to prematurely terminate the function, this output statement is not executed and the text does not appear in the output.
It is also worth noting that a return statement is not required
to terminate a function. If the function simply runs out of statements
to execute, it will terminate naturally and return control to the code
from which it was invoked.
<!-- File Js00000250.htm
Copyright 1998, R.G.Baldwin
This script is designed to illustrate the use of return to
terminate a function prematurely.
The output from running this script is:
Call myFunction with parameter value of 6
Enter myFunction
Still in myFunction
Back from myFunction
Call myFunction with parameter value of 5
Enter myFunction
Back from myFunction
Done.
-------------------------------------------------------------------->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
function myFunction(data){
document.write("Enter myFunction<BR>");
if(data == 5) return;
document.write("Still in myFunction<BR>");
}//end myFunction()
// End hiding -->
</SCRIPT>
</HEAD>
<BODY>
<SCRIPT LANGUAGE="JavaScript1.2">
<!-- Hide script
document.write("Call myFunction with parameter value of 6<BR>");
myFunction(6);
document.write("Back from myFunction<BR><BR>");
document.write("Call myFunction with parameter value of 5<BR>");
myFunction(5);
document.write("Back from myFunction");
// End hiding -->
</SCRIPT>
<P> Done.
</BODY>
</HTML>
|