Richard G Baldwin (512) 223-4758, baldwin@austin.cc.tx.us, http://www.austin.cc.tx.us/baldwin/

JavaScript Programming, Functions Revisited

 
Java/Web Programming, Lecture Notes # 2145, Revised 05/26/98.

Preface

The material was prepared as part of a new tutorial that I plan to publish on Web programming in general.  It is not part of the Java academic curriculum at ACC.

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.

 

Introduction

Because of the special needs to understand functions early, a preview of functions was given in one of the early lessons in this tutorial.  We will revisit the topic now and discuss aspects that you probably didn't have the background to understand earlier.
 

Functions Revisited

Functions, or procedures as they are called in some languages, provide a fundamental building block for virtually every programming language.  The purpose of a function is to encapsulate the ability to perform a given task into a single set of code and to be able to invoke or execute that single set of code from a variety of locations within the script.  This can eliminate the requirement to repeat the same code over and over when the need to perform the same task is required at many points in the script.

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:

(It is also possible to instantiate function objects which will be the topic for a subsequent lesson.)

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()
 
This function definition contains all of the basic parts:

This function is somewhat simpler than one that could be used to calculate the surface area of a sphere, but the basic concept is the same.  This function expects to receive a parameter which it knows locally by the name incomingParameter.

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>");
 
The call to the function is embedded in the argument list of a call to a different function named write().  This is a special kind of function that we call a method.  We will learn more about methods in a subsequent lesson.

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 
window. 

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.

 
This script makes a call to the function named getHalf() passing a parameter to that function.  getHalf() returns a value that is half the value of the incoming parameter.

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>
 
All functions in JavaScript have global scope.  You can call any function defined in the current page from any code on the page. You can also use functions defined by other named windows or frames.  We will discuss this in a subsequent lesson where we discuss the use of JavaScript with Navigator frames.

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.
 

Passing Objects to Functions

The arguments of a function are not limited to strings and numbers. You can also pass objects to a function.  The following script illustrates the passing of an anonymous object to a function named showDate.

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 purpose of the function is to extract the necessary information about dates and times from the incoming object and display that information.  Because we already should know how to display such information, I won't discuss the document.write() statements in this sample script.

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";
 
The one final code fragment that I want to highlight from this sample script is not in the function.  Rather, it is a call to the function in the body of the HTML document.  This call will cause the message regarding the date and time to appear at the location in the HTML document where the call is placed.

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());
 
You can view the complete script in context in the following box.
 
<!-- 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

Recursion is the process of allowing a function to make another call to itself.  Recursion can provide an elegant solution to certain types of problems such as searching directory trees.

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

The Arguments Array

The arguments of a function are maintained in an array. As you are already aware, within the function you can access the parameters by referring to their local names as defined in the argument list for the function.  However, you can also access the parameters as the elements of an array using indexed-array notation. The name of the array is the same as the name of the function.

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.
 

Variable Numbers of Arguments

Suppose like me, you get tired of typing document.write every time you want to write a statement that will put text on the screen.  Not only is this burdensome, it takes up so much space on the line that by the time you indent properly and type in these two words, there is often very little room left on the line for the arguments that you want to pass to the write() function.

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
 
In order to display a string of arguments on the screen, all that is required is to make a call to the function d() passing the arguments as parameters as shown below.  The following code fragment was extracted from the body of the HTML document in the sample script that follows.
 
      d("The value of x is ", x, " and the value of y is ", y);
 
Not only is this a useful function, it is also a good example of the value of having the capability to define and use functions.

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

Function Overloading

Function overloading is a term used in object-oriented programming to indicate that it is allowable to have two or more functions with the same name that have different behavior.  Both C++ and Java support function overloading as an intrinsic part of the language.

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
 
JavaScript code in the body of the HTML document makes three calls to the overloaded function; once with one parameter, once with two parameters, and once with three parameters.
 
      overFun(6.28);
      overFun("First argument ",3.14159);
      overFun(1,2,3);      
 
The behavior is as expected as evidenced by the output shown in the comments in the beginning of the complete listing that follows.
 
<!-- 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>
 
-end-