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.
For example, if you write a script that frequently needs to calculate the surface area of a sphere, you can encapsulate those calculations into a function. Then, whenever your script needs to know the surface area of a sphere, it can simply call the function providing the radius of the sphere as a parameter. The function will perform the calculation and return the answer to be used by the script at that point.
A JavaScript function definition has the following basic parts:
There are two sides to every function: the definition and the call.
The definition names the function and specifies how it will behave when it is called.
The call to the function temporarily passes control to the statements in the function allowing them to behave as previously defined. Once the statements have been executed, control is returned to the point in the script where the call was made.
As in the sphere example discussed above, it is often useful to pass information to the function for it to use in doing whatever it is supposed to do (but this is not always required). When we call the function, we can include parameters in the call to the function that match up with the argument list mentioned above. (In fact, we can pass parameters to the function that do not match up with the argument list mentioned above. This is discussed in detail near the end of this lesson.) The code in the function can then use those parameters to do its job.
Remember that we are dealing with HTML pages that are normally downloaded from a server. The download process often experiences delays. You should define all of your functions in the header portion of the HTML page. That will ensure that all functions are downloaded and defined before any of the content of the page is displayed. This will prevent the user from taking an action that needs the function before it is fully defined.
Usually (but not always), the purpose of a function is to calculate or otherwise determine some value and return it. In the sphere example mentioned earlier, the purpose of the function would be to calculate and return the surface area of the sphere. Returning a value is accomplished using the return keyword in the body of the function.
Sometimes the purpose of a function is simply to perform an action without returning anything. For example, you might write a function that causes an audible alarm to be sounded. Then whenever your script needs to cause the audible alarm to be sounded, it can call the function.
The following sample HTML page uses JavaScript to define a function
named getHalf() in the header portion of the page. The function
definition is shown below.
function getHalf(incomingParameter) { return incomingParameter/2; }//end function getHalf() |
It calculates and returns half the value of the incoming parameter using the return keyword, the division operator, and the literal value 2.
The function is called twice in the body of the page, passing a different
value for the parameter each time. One such call is shown below.
document.write("Half the number is: ", getHalf(10.6),"<BR>"); |
write() is a method of the predefined Navigator object named
document. Here is a description of the write() method
including information extracted from the Netscape documentation.
write
Writes one or more HTML expressions to a document in the specified
Syntax document.write(expr1, ...,exprN) Parameters expr1, ... exprN Any JavaScript expressions.
Description The write method displays any number of expressions in the document window. You can specify any JavaScript expression with the write method, including numeric, string, or logical expressions. |
As a practical matter, the call to the function is replaced by the value that it returns in the expression in which the function call appears. This value is then passed as a parameter to the method named write() where it is displayed on the screen.
It is a principle of good programming design that each function should perform only one task, and should perform it well. The task performed by the function named getHalf() is to calculate and return half the value that it receives, and it does that job very well.
A complete listing of the script follows.
<!-- File Js000050.htm -----------------------------------> <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript1.2"> <!-- Hide script //Define the function named getHalf() function getHalf(incomingParameter) { return incomingParameter/2; }//end function getHalf() // End hiding --> </SCRIPT> </HEAD> <BODY> <SCRIPT> //Call the function passing 10.6 as a parameter. document.write("Half the number is: ", getHalf(10.6),"<BR>"); //Call the function again passing 12.3 as a parameter. document.write("Half the number is: ", getHalf(12.3)); </SCRIPT> <P> Done. </BODY> </HTML> |
To reiterate something that we alluded to earlier. Simply defining
a function does not cause it to be executed. After you define the
function, you must execute JavaScript statements that actually call the
function in order to execute it.
The output from this script is:
The date and time is 11:41 PM on 5/25/98
The date and time that will be displayed will be the local date and time based on the clock in the client machine.
The function named showDate() is designed to extract the necessary information from an object of type Date and display that information in the format shown above. The function doesn't return anything. As indicated earlier, this a function that is designed to perform an action rather than to calculate and return a value.
For the reasons recommended earlier, the function definition is placed
in the header portion of the HTML document. The function begins with
the following which is often referred to as the function signature
in other programming environments. As you can see, the name of the
function is showData and it receives a parameter that it knows locally
by the name dateObject. The expected parameter is an object of type
Date.
function showDate(dateObject){ |
The necessary information is extracted from the object by invoking functions such as getMonth(), and getDate() on the object. Each of these method calls returns one piece of the information.
Skipping ahead, the next fragment shows an interesting block of code that converts the hour in military time to the hour in the AM, PM format that most of us are more familiar with. In this code fragment, after getting the hour information encapsulated in the incoming object and assigning it to a local variable named theHour, we test to see if it is greater than 12 and if so subtract 12 from it. This causes the hour value to go from zero to 12 twice each 24 hours.
Then depending on whether the hour is less than or greater than 12,
we define a new local variable named amPm and set it to the correct
string for the hour: AM or PM. Both theHour
and amPm are used later to display the time.
theHour = dateObject.getHours(); if(theHour > 12){ theHour -= 12; amPm = " PM"; }else amPm = " AM"; |
Notice that the new Date object is instantiated by including
the new operator and the constructor for the object directly
in the argument list of the function call. In other programming environment,
this is often referred to an an anonymous object because the object
is instantiated without directly assigning it to a named variable.
This syntax causes the object to be instantiated and passed as a parameter
to the function where it is taken apart to obtain the needed information.
showDate(new Date()); |
<!-- File Js00000380.htm Copyright 1998, R.G.Baldwin This script is designed to illustrate the passing of anonymous objects to functions. The output from running this script is: The date and time is 11:41 PM on 5/25/98 Done. --------------------------------------------------------------------> <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript1.2"> <!-- Hide script function showDate(dateObject){ document.write("<P>The date and time is "); theMonth = dateObject.getMonth() + 1; theDay = dateObject.getDate(); theYear = dateObject.getYear(); theHour = dateObject.getHours(); if(theHour > 12){ theHour -= 12; amPm = " PM"; }else amPm = " AM"; theMin = dateObject.getMinutes(); document.write(theHour + ":" + theMin + amPm + " on "); document.write(theMonth + "/" + theDay + "/" + theYear); }//end function showDate() // End hiding --> </SCRIPT> </HEAD> <BODY> <SCRIPT> <!-- Hide script showDate(new Date()); // End hiding --> </SCRIPT> <P> Done. </BODY> </HTML> |
Recursion can also be difficult for some people to grasp. It is very easy to crash your system while testing recursive programs if you don't really understand the concepts involved.
Therefore, my primary purpose here is to make you aware that JavaScript supports recursion and to show you a simple example.
However, I won't attempt to teach you about recursion in this lesson.
If you don't already understand recursion and are interested, I recommend
that you go to the library and get a book that explains the topic in detail.
The sample script that uses a recursive function follows.
<!-- File Js00000390.htm Copyright 1998, R.G.Baldwin This script is designed to illustrate recursion. The output from running this script is: 0 factorial is 1 1 factorial is 1 2 factorial is 2 3 factorial is 6 4 factorial is 24 Done. --------------------------------------------------------------------> <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript1.2"> <!-- Hide script function factorial(n) { if ((n == 0) || (n == 1)) return 1 else { result = (n * factorial(n-1) ) return result }//end else }//end function // End hiding --> </SCRIPT> </HEAD> <BODY> <SCRIPT> <!-- Hide script for (cnt = 0; cnt < 5; cnt++) { document.write("<BR>", cnt, " factorial is ", factorial(cnt)) } // End hiding --> </SCRIPT> <P> Done. </BODY> </HTML> |
There isn't even a requirement that you define local parameters when you define the function. (I indicated that the comma separated argument list is optional early in this lesson where I listed the parts of a function definition.)
IMPORTANT: JavaScript allows you to call the function passing more parameters than were originally specified in the formal argument list.
There are several benefits to this approach. First, it allows
you to define and use arrays that have a variable number of arguments.
Second, it allows you to implement a crude form of function overloading.
We will see sample scripts illustrating both.
The following script deals with this problem. The script defines a short function named d() for display (how's that for shortening the name). This function is defined to take no arguments. Inside the function, a for loop tests for the length of the argument array (also named d), extracts each of the elements from the array in succession, and displays each of them on the screen by executing a document.write() function call passing the element from the array to the function.
Once all of the elements have been passed to the document.write()
method, the method is called one more time passing an HTML line break ("<BR>")
to the method.
function d(){ for(cnt = 0; cnt < d.length; cnt++) document.write(d[cnt]);//end for loop document.write("<BR>");//write a line break }//end function |
d("The value of x is ", x, " and the value of y is ", y); |
The following box contains the complete script with everything in context.
<!-- File Js00000400.htm Copyright 1998, R.G.Baldwin This script is designed to illustrate use of the arguments array. The output from running this script is: The value of x is 10 and the value of y is 20 Done. --------------------------------------------------------------------> <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript1.2"> <!-- Hide script function d(){ for(cnt = 0; cnt < d.length; cnt++) document.write(d[cnt]);//end for loop document.write("<BR>");//write a line break }//end function // End hiding --> </SCRIPT> </HEAD> <BODY> <SCRIPT> <!-- Hide script x = 10, y = 20; d("The value of x is ", x, " and the value of y is ", y); // End hiding --> </SCRIPT> <P> Done. </BODY> </HTML> |
In both languages, the compiler distinguishes between two or more functions having the same name on the basis of their argument list. Even though the names of the functions can be the same, the argument lists must differ in such a way that the compiler can examine the actual arguments being passed to the function when it is called and determine which version of the overloaded function should be called in that instance.
Function overloading supports something called compile-time polymorphism. Polymorphism is a requirement for any programming language that claims to be an object-oriented programming language. (See the early lessons in my Java tutorials for more discussion of polymorphism.)
JavaScript doesn't support function overloading as an intrinsic part of the language. However, the ability to define functions that can have different numbers of arguments makes it possible to simulate function overloading. The trick is to write one function having two or more blocks of code and execute the appropriate block when the function is called based on the number of arguments passed to the function.
It should also be possible to augment this process by using the typeof operator to determine the types of arguments passed to the function in those cases where the number of arguments isn't sufficient to differentiate between two different situations.
The following sample script simulates function overloading in JavaScript. A function named overFun() is defined that can accept either one argument or two arguments, but doesn't know what to do with any other number of arguments. This last situation must be dealt with at runtime in JavaScript, whereas it would be dealt with at compile time in C++ and Java.
This script uses the function named d() developed earlier to display information on the screen. You can see the code for that function in the complete listing of this script that follows this discussion.
The "overloaded function" named overFun() uses a switch statement to select among three blocks of code depending on the number of parameters passed when the function is called. If it receives one parameter, it displays that parameter and returns. If it receives two parameters, it displays both of them and returns. If it receives any other number of parameters, it displays an error message and returns.
In a script that is intended to do some real work, the code to do the
work would be placed in the blocks between the case constant and
the corresponding break.
function overFun(){ len = overFun.length; switch (len){//simulates two overloaded functions case 1: d("Function with one argument, display it"); d(overFun[0]); break; case 2: d("Function with two arguments, display them"); d(overFun[0],overFun[1]); break default: d("No match for ", len, " arguments"); }//end switch statement }//end overFun |
overFun(6.28); overFun("First argument ",3.14159); overFun(1,2,3); |
<!-- File Js00000410.htm Copyright 1998, R.G.Baldwin This script is designed to illustrate use of the arguments array. The output from running this script is: Call three overloaded functions in succession Function with one argument, display it 6.28 Function with two arguments, display them First argument 3.14159 No match for 3 arguments Done. --------------------------------------------------------------------> <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript1.2"> <!-- Hide script function d(){//simple display function for(cnt = 0; cnt < d.length; cnt++) document.write(d[cnt]);//end for loop document.write("<BR>");//write a line break }//end function function overFun(){ len = overFun.length; switch (len){//simulates two overloaded functions case 1: d("Function with one argument, display it"); d(overFun[0]); break; case 2: d("Function with two arguments, display them"); d(overFun[0],overFun[1]); break default: d("No match for ", len, " arguments"); }//end switch statement }//end overFun // End hiding --> </SCRIPT> </HEAD> <BODY> <SCRIPT> <!-- Hide script d("Call three overloaded functions in succession"); overFun(6.28); overFun("First argument ",3.14159); overFun(1,2,3); // End hiding --> </SCRIPT> <P> Done. </BODY> </HTML> |