Chapter 6. Building and Calling Functions

CONTENTS

CONTENTS>>

  •  Methods and Functions
  •  Creating Functions
  •  Firing Functions with Event Handlers
  •  The return Statement
  •  Using Functions as Data
  •  Properties in Functions
  •  Methods in Functions
  •  Summary

In discussing the different structures, objects, statements, operators, and expressions in JavaScript, you have seen several examples using functions. Chapter 3, "Dealing with Data and Variables," explained global and local variables and discussed how local variables are defined inside of function definitions. Chapter 1, "Jump-Starting JavaScript," showed how JavaScript in the deferred mode uses functions with event handlers to enable the designer to build a page that responds to the user's actions with input devices. This chapter focuses on the different uses and constructions for functions.

Methods and Functions

In previous and subsequent chapters, you will see references to methods and discussions about methods that make them sound a good deal like functions. To help clarify the difference between methods and functions, this section skips ahead a bit to a discussion of objects in JavaScript. (The next chapter discusses objects in detail.)

Objects are collections of properties arranged in a hierarchy. The highest level of objects in the context of JavaScript and an HTML page is the window. Everything in an HTML page is a property of the window object. When a function is the property of an object, it is called a method. However, technically speaking, because everything in an HTML page is a property of the window object, all functions are methods associated with the window property. When using most methods, you must specify the object with which they are associated. For example, the following script uses a method and function found in previous chapters:

<html>     <head>     <title>String Function/Method</title>     <script language="JavaScript">     var fullName = "Willie B. Goode";     var address="123 Polar Bear Drive";     address=address.toLowerCase();     window.document.write(fullName + "<br>" + address);     </script>     </head>     <body bgcolor="snow">     </body>     </html>

The output of the script is this:

Willie B. Goode     123 polar bear drive

The string variable address has a property that functions to change all of the characters in the string to lowercase. The function, toLowerCase(), is called a method because, in this case, it always is going to refer to the string object of which it is a property. The other string in the script, fullName, is not affected at all by the function because the function (method) is not used as a property of the fullName string variable.

In the same script, the familiar write() function is used to print the two strings to the screen. However, the full line is window.document.write(). As you can see, both document and write() are properties of the window object; hence, the write() function can be seen as a method. The reason that write() and many other built-in functions (such as alert() and prompt()) are considered functions instead of methods is that it is unnecessary to write the window object to fire off a function that is actually a property of the window object. For example, try the following little script, in which two built-in functions can clearly be seen as methods of the window object:

<html>  <head>  <title>Built-in Window methods</title>  <script language="JavaScript">  var watchThis=window.prompt("Enter your name","");  window.alert("See I told you " + watchThis + " that functions are really methods.");  </script>  </head>  <body bgcolor="white">  </body>  </html>

While it should be clear that built-in functions are actually properties of and, therefore, methods of the window object, is the same true about user functions? Yes, it is. User functions are called methods when attached to an object. A script is worth a thousand words:

<html>  <head>  <title>User Window methods</title>  <script language="JavaScript">  function reallyMethod() {       window.document.write("I\'m really a method!");        }  window.reallyMethod();  </script>  </head>  <body bgcolor="white">  </body>  </html>

As you can see when you run the script, the user function is, in fact, a method in this case. The distinction between functions and methods, in a very strict sense, is artificial. However, in a practical sense, distinguishing between the two is helpful. If a method is a property of the window object and nothing else, it is called a function. If a function is a property of a lower-level specific object, it's called a method. In some contexts, you will find the terms used interchangeably. However, the important point is that all functions are properties of objects.

Creating Functions

Creating a function involves stating a function name and then adding a series of statements or other functions between curly braces. The general format is as follows:

function functionName(optional arguments) {    statements or other functions     } 

For example, the following function in the following script can be used to determine the number of 1 x 8 boards needed for a shed's walls. The two arguments in the function, front and side, are used as variables in two prompt functions.

<html>  <head>  <title>Shed Planner</title>  <script language="JavaScript">  function shedWalls(front,side) {       var front=prompt("How many feet across the front?","");        var side=prompt("How many feet along the side?","");        var numFront=(front * 12 * 2)/8;        var numSide=(side * 12 * 2)/8;        var total=numFront+numSide;        var message="You will need " + total + " one by eight-inch boards for your        shed walls."        document.write(message);        }  shedWalls();    //The function is called  </script>  </head>  <body bgcolor="palegoldenrod">  </body>  </html>

The shedWalls() function is launched from within the <script> container simply by placing the function in sequence after the definition.

It would have been simpler to leave out the function format altogether and simply have written the sequence of statements that were within the function itself. For functions to play the role that they were designed to play, they should be launched independently by an action taken by the user. This next section examines the events and event handlers used by JavaScript.

Firing Functions with Event Handlers

Chapter 10, "Event Handlers," examines event handlers in detail. Here, however, you need to know how event handlers launch a JavaScript function. Chapter 10 explores the nuances of event handlers and the several different ones that are available in HTML and JavaScript.

Event Categories

Events can be divided into three main general categories:

  • Keyboard and mouse events

  • Load events

  • Form-related events

Errors and window resizing can also be handled as events. Trapping errors can be used both in debugging and to keep a script from crashing. However, in this chapter, all the focus is on the main categories and how an event from any one works to fire a JavaScript function.

Mouse and Keyboard Events

Setting up functions to work with user-generated events from the keyboard or mouse is very different. As seen in previous chapters, capturing a mouse event is quite simple. Within a "hot" area on the page, such as a link or button object that detects mouse actions, you can launch a function in a script. For example, the following script keeps a running record of the mouse moving using the onMouseMove event handler from HTML. (NN6+ or IE5+ is required for this next script.)

<html>  <head>  <title>MouseMove</title>  <script language="JavaScript">  var recordIt=0  function moveIt() {       recordIt += 1;        document.viewer.spot.value=recordIt;        }  </script>  </head>  <body bgcolor="pink">  <center>  <p>  <h2>How many mouse moves?</h2>  <form name="viewer">  <input type=text name="spot" size=3>  </form>  <a href=javascript:void onMouseMove="moveIt()">Tickle this spot</a>  </body>  </html>

To set up a dummy link, I used javascript:void as the reference point so that the link wouldn't try to jump elsewhere. (You can use the pound sign [#] to do pretty much the same thing.) The onMouseMove event handler from HTML fires the function named moveIt(). By incrementing a variable in the text box window each time the function is fired, you can get a better idea of how the event is recorded. If you change the script by substituting onMouseOver for onMouseMove, you will see that the text window indicates a new event only when the mouse is first over the hotspot. However, as long as any mouse movement is recorded with the onMouseMove event, the function is fired until the pointer is off the hotspot. Figure 6.1 shows the screen with the recorded movement as the pointer moves over "Tickle this spot" on the HTML page.

Figure 6.1. Any movement over the hotspot using onMouseOver fires the function to increment a variable stored in the text window.

graphics/06fig01.gif

Keyboard events require a whole different tactic of scripting and might even be considered a form-related event. They are discussed in detail in Chapter 10.

Load Events

When a page first appears on the screen, it "loads"; when it leaves, it "unloads." Both of these events can be captured as part of the <body> tag. Either an onLoad or an onUnload event handler within the <body> tag launches a function. The following shows how to launch a function as soon as a link to another page is clicked:

<html>  <head>  <title>unLoad</title>  <style>  h1 { color:red;                    background-color:white                    }  </style>  <script language="JavaScript">  function lastChance() {       var message="Thanks for visiting and please come again.";        alert(message);        }  </script>  </head>  <body bgcolor="dimgray" onUnload="lastChance()">  <p>  <center>  <h1>Red Hot Page</h1>  </center>  </body>  </html>

The user is only indirectly involved with firing the function. Whereas a mouse click on a hotspot can fire a function repeatedly, a page loads and unloads only once. Be judicious in your use of onUnload. When people click a link to go somewhere else, they might not appreciate any delays.

Form-Related Events

The several form-related events are discussed in detail in Chapter 10, and here an example serves to illustrate how one form-related event works in firing a function. Unlike some of the other events that require a hotspot, the form-related events require a form. For example, the onFocus and onUnfocus events refer to placing the cursor into or removing it from an input text window within a form. When the writing cursor (I-beam) is placed into a text window, a "focus" event occurs and an onFocus event handler fires a function. The following script shows how a function can automatically fill a window:

<html>  <head>  <title>Focus This</title>  <script language="JavaScript">  function fillItIn() {       //Substitute your own email address on the next line        document.info.email.value="bill@sandlight.com";        }  </script>  </head>  <body bgcolor="gainsboro">  <p>  <form name="info">  Please enter your email address:  <input type=text name="email" onFocus="fillItIn()">  </form>  </body>  </html>

As soon as you click the text window with your mouse pointer, the window should fill with the selected text. If you are using several text windows, pressing the Tab key on the keyboard will sequentially move text from one text window to the next. If you have an onFocus event handler for each text input window, you can provide a function to fill in each one.

The return Statement

The return statement is discussed here instead of in the last chapter because the statement can be used only as part of a function. The role of the return statement is to provide the value of the expressions within the function. But where does the function return the value to? For example, try out the following script:

<html>  <head>  <title>Return</title>  <script language="JavaScript">  function returnMessage() {       var part1="Good ";        var part2="Morning";        var wholeThing=part1 + part2;        return wholeThing;        }  returnMessage();  </script>  </head>  <body bgcolor="mistyrose">  </html>

When you run the previous program, nothing appears on your screen other than having a nice, misty, rose-colored screen. The string value "Good Morning" was returned in the function. However, nothing in the function tells the script where to put the information in the function. Now, rewrite the script as follows:

<html>  <head>  <title>Return</title>  <script language="JavaScript">  function returnMessage() {       var part1="Good ";        var part2="Morning";        var wholeThing=part1 + part2;        return wholeThing;        }  var putItOut=returnMessage();  document.write(putItOut);  </script>  </head>  <body bgcolor="mistyrose">  </html>

Now the script should provide you with a "Good Morning" greeting on the screen. By placing the function into a variable and directing that variable to be placed on the screen using the document.write() function, you have specified where you want the returned value to go. No doubt you might be wondering why you should use the return statement at all, and instead simply place a document.write (wholeThing) statement in the function to accomplish the same task. For optimizing the current script, the latter script might indeed be better; however, by using the return statement, you can treat the function as data in a variable or object.

In the previous script, try commenting out the return line like this:

//return wholeThing; 

Save the script and run it again. On the second attempt, you should see "undefined" on the screen instead of "Good Morning." The value in the function is not returned, and so nothing is the value of the function. When nothing is placed into a variable, the return is always undefined. So, when you create a function in JavaScript, you need to remember to provide a return statement in the script if you plan to use the function as data in another expression.

Using Functions as Data

As illustrated in the previous section, functions can be treated as data. Like any other data, functions express some type of value, whether it be string, numeric, or Boolean. This next section considers two more methods of creating functions. The first method uses the Function() constructor, and the second uses function literals.

Using the Function() Constructor

The Function() constructor looks like the new object or array constructor. It has this general format:

var variableName=new Function("exp1", "exp2", "return exp3;"); 

Here, exp1 is a necessary first expression, exp2 is an optional second expression, and exp3 is an expression made up of exp1 and exp2. For example, the following script uses item as exp1 and tax as exp2 to generate a function that computes the total cost of an item, including tax:

<html>  <head>  <title>Function constructor</title>  <script language="JavaScript">  var total=new Function("item","tax", "return item +=tax");  document.write("Your bill is $" + total(14.43,.06));  </script>  </head>  <body bgcolor="thistle">  </html>

Unlike the function statement, the Function() constructor uses parentheses rather than curly braces, and all elements of the function are separated by commas. Also, the function has no name. Instead, the function-as-a-value is immediately placed into a named variable, and references to the function can be made through references to the variable name.

Using Function Literals

A newer version of the Function() constructor can be found in function literals. Function literals look more like function statements, in that they use curly braces. However, like the Function() constructor, they have no unique name of their own for purposes of reference. Their general format is as follows:

var variableName=new function(arg1,arg2) {return exp1}; 

Using the same parameter as in the Function() constructor example, you can see the similarities and differences in creating and using values derived from functions.

<html>  <head>  <title>Function Literal</title>  <script language="JavaScript">  var total=function(item,tax) {return item +=tax};  document.write("Your bill is $" + total(14.95,.06));  </script>  </head>  <body bgcolor="wheat">  </html>

Using functions as literal data provides a lot more flexibility in your scripts. Instead of invoking just a single function with an event handler, you can invoke a function that contains literals made up of other functions. Keep in mind when you begin using function literals in other functions that your scripts can exponentially increase in complexity and difficulty in debugging. However, rather than being a reason not to use function literals, this suggests keeping your script well organized so that you can see where everything belongs.

Properties in Functions

JavaScript functions are objects, and, as such, they contain properties. An important built-in property is length. The length property is a read-only one that returns the number of arguments that are supposed to be in a function. When you define a function, you can put in as many or as few, including zero, arguments in the function as you want. The number of arguments that you include becomes the value of the function's length.

However, when you actually invoke a function, the number of arguments that you include may not match the number that you defined. The mismatch of defined and invoked arguments need not lead to your program crashing, but if the two are equal, you can be assured that the script is working as structured. A function property, arguments, has a length property as well. From arguments.length, you can find the actual number of arguments used in the function when it is invoked. By comparing the two values, you can debug your script. The following script uses a function with an unused but counted argument in the definition and three unused arguments when invoked. The output tells you whether they match.

<html>  <head>  <title>Function Properties</title>  <script language="JavaScript">  function bogus(xx) { //The 'xx' is the argument        var alpha=arguments.length;        var beta=bogus.length;        return alpha + " arguments, but should use " + beta + " argument/s."        //When the bogus.length run it returns 1 because it only has 1 argument.        }  document.write("This function uses " + bogus(3,4,5));  </script>  </head>  <body bgcolor="moccasin">  </html>

As the name of the function implies, none of the arguments is used in the function. They are there only to illustrate how to access the properties and the fact that the arguments do exist as properties, whether they are used or not. Change the number of arguments in the bogus() function definition and in the statement that invokes the function to see the different feedback that you get on the screen. (Other browser-specific properties are available but, to minimize confusion, they are not discussed here.)

Methods in Functions

Only a single standard method object is available at this time for functions. Several other browser-specific methods are available but, as noted previously, this book focuses primarily on those that can be used with any browser. The method converts the output of a function to a string using the toString() method. It can be added to any function object. This format changes all numeric or Boolean values to strings:

functionName.toString() 

The following script provides an illustrative example of how the method works:

<html>  <head>  <title>Illustrating toString()</title>  <script language="JavaScript">  function alpha() {       var hope = 12;        var charity = 10;        return hope > charity;        }  function beta() {        var now = 57;         var then = 3;         return now / then;         }  var header="<h2>Functions in Strings and Numbers </h2>"  var indigo = alpha();  var denim=beta();  var boole = alpha().toString();  var lean = beta().toString();  var twoStrings= boole + lean;  var stringer ="The functions converted to strings return-> ";  var sumnum ="The regular functions return the sum, ";  var numnum=indigo + denim;  document.write(header + stringer + twoStrings + "<p>" + sumnum + numnum);  </script>  </head>  <body bgcolor="lightyellow">  </body>  </html>

The purpose of including a Boolean value in the function alpha is to show that, expressed as a string, the value returns a true and, as a number, it returns the value 1. When the two functions are converted to strings using the toString() method, the output is a concatenation of true and 19. However, without the conversion, the value 20 is returned. Figure 6.2 shows the output on the screen.

Figure 6.2. The toString() method used with functions converts all numeric values to strings.

graphics/06fig02.gif

Summary

Functions are the bedrock of interactive JavaScript on the World Wide Web. Because functions, combined with event handlers, allow for a delayed response based on the user's action, they respond to an action and hence are interactive. So, virtually all events triggered by the user's action are potential sources for launching functions and engaging the user in ways that a static web page cannot do alone.

For the most part, functions are built as independent objects and are launched by a triggering event. However, they can be treated as data and can be placed into variables for use in other statements, including other functions as arguments or a part of other objects. As such, functions can be treated as modular building blocks in an object-oriented format for creating sophisticated but very clear scripts.

In developing your functions, use clear, concise code that you can reuse in other scripts. As you get better, your functions can be placed into libraries or an application program interface (API) and can be brought into your pages by an externally saved file with key JavaScript functions ready to use. All you have to do is call them into the new script, and a good hunk of your work will be done.

CONTENTS


JavaScript Design
JavaScript Design
ISBN: 0735711674
EAN: 2147483647
Year: 2001
Pages: 25

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net