Section 8.1. Defining and Invoking Functions


8.1. Defining and Invoking Functions

As shown in Chapter 6, the most common way to define a function is with the function statement. This statement consists of the function keyword followed by:

  • The name of the function

  • Zero or more parameter names contained within parenthesis, each separated by commas

  • The JavaScript statements that comprise the body of the function, contained within curly braces

Example 8-1 shows the definitions of several functions. Although these functions are short and simple, they all contain each of the elements just listed. Note that functions may be defined to expect varying numbers of arguments and that they may or may not contain a return statement. The return statement was introduced in Chapter 6 ; it causes the function to stop executing and to return the value of its expression (if any) to the caller. If the return statement does not have an associated expression, it returns the undefined value. If a function does not contain a return statement, it simply executes each statement in the function body and returns the undefined value to the caller.

Example 8-1. Defining JavaScript functions

 // A shortcut function, sometimes useful instead of document.write() // This function has no return statement,     so it returns undefined. function print(msg) {     document.write(msg, "<br>"); } // A function that computes and returns the distance between two points function distance(x1, y1, x2, y2) {     var dx = x2 - x1;     var dy = y2 - y1;     return Math.sqrt(dx*dx + dy*dy); } // A recursive function (one that calls itself) that computes factorials // Recall that x! is the product of x and all positive integers less than it function factorial(x) {     if (x <= 1)         return 1;     return x * factorial(x-1); } 

Once a function has been defined, it may be invoked with the () operator, introduced in Chapter 5. Recall that the parentheses appear after the name of the function (actually, any JavaScript expression that evaluates to a function value may be followed by parentheses) and that an optional comma-separated list of argument values (or expressions) appears within the parentheses. The functions defined in Example 8-1 can be invoked with code like the following:

 print("Hello, " + name); print("Welcome to my blog!"); total_dist = distance(0,0,2,1) + distance(2,1,3,5); print("The probability of that is: " + factorial(5)/factorial(13)); 

When you invoke a function, each expression you specify between the parentheses is evaluated, and the resulting value is used as an argument of the function. These values are assigned to the parameters named when the function was defined, and the function operates on its parameters by referring to them by name. Note that these parameter variables are normally available only within the body of the executing function: they cannot normally be accessed outside the body of the function or after the function has returned. (But see Section 8.8 for an important exception.)

Since JavaScript is a loosely typed language, you are not expected to specify a datatype for function parameters, and JavaScript does not check whether you have passed the type of data that the function expects. If the datatype of an argument is important, you can test it yourself with the typeof operator. JavaScript does not check whether you have passed the correct number of arguments either. If you pass more arguments than the function expects, the function ignores the extra argumetns. If you pass fewer than expected, the parameters you omit are given the undefined value. Some functions are written to tolerate omitted arguments, and others behave incorrectly if you don't pass all the arguments they expect. Later in this chapter, you'll learn how a function can determine exactly how many arguments it was passed and can access those arguments by their position in the argument list rather than by name.

Note that the print() function defined in Example 8-1 does not contain a return statement, so it always returns the undefined value and cannot meaningfully be used as part of a larger expression. The distance() and factorial() functions, on the other hand, can be invoked as parts of larger expressions, as shown in the previous examples.

8.1.1. Nested Functions

In JavaScript, functions may be nested within other functions. For example:

 function hypotenuse(a, b) {     function square(x) { return x*x; }     return Math.sqrt(square(a) + square(b)); } 

Nested functions may be defined only at the top level of the function within which they are nested. That is, they may not be defined within statement blocks, such as the body of an if statement or while loop.[*] Note that this restriction applies only to functions defined with the function statement. Function literal expressions, which are described in the next section, may appear anywhere.

[*] Different implementations of JavaScript may be more relaxed about function definitions than the standard requires. For example, Netscape's implementation of JavaScript 1.5 allows "conditional function definitions" that appear within if statements.

Some interesting programming techniques involve nested functions, and I'll have more to say about them later in the chapter.

8.1.2. Function Literals

JavaScript allows functions to be defined with function literals. As discussed in Chapter 3, a function literal is an expression that defines an unnamed function. The syntax for a function literal is much like that of the function statement, except that it is used as an expression rather than as a statement and no function name is required. The following two lines of code define two more or less identical functions using a function statement and a function literal, respectively:

 function f(x) { return x*x; }              // function statement var f = function(x) { return x*x; };       // function literal 

Although function literals create unnamed functions, the syntax allows a function name to be optionally specified, which is useful when writing recursive functions that call themselves. For example:

 var f = function fact(x) { if (x <= 1) return 1; else return x*fact(x-1); }; 

This line of code defines an unnamed function and stores a reference to it in the variable f. It does not store a reference to the function into a variable named fact, but it does allow the body of the function to refer to itself using that name. Note, however, that this type of named function literal was not properly implemented before JavaScript 1.5.

Because function literals are created by JavaScript expressions rather than statements, they are quite flexible and are particularly well suited for functions that are used only once and need not be named. For example, the function specified by a function literal expression can be stored into a variable, passed to another function, or even invoked directly:

 f[0] = function(x) { return x*x; };  // Define a function and store it a.sort(function(a,b){return a-b;});  // Define a function; pass it to another var tensquared = (function(x) {return x*x;})(10);  // Define and invoke 

8.1.3. Naming Functions

Any legal JavaScript identifier can be a function name. Try to choose function names that are descriptive but concise. Striking the right balance is an art that comes with experience. Well-chosen function names can make a big difference in the readability (and thus maintainability) of your code.

Function names are often verbs or phrases that begin with verbs. It is a common convention to begin function names with a lowercase letter. When a name includes multiple words, one convention is to separate words with underscores like_this(); another convention is to begin all words after the first with an uppercase letter likeThis(). Functions that are supposed to be internal or hidden are sometimes given names that begin with an underscore.

In some styles of programming, or within well-defined programming frameworks, it can be useful to give frequently used functions very short names. The client-side JavaScript framework Prototype (http://prototype.conio.net), for example, elegantly uses a function named $() (yes, just the dollar sign) as an intelligent replacement for the very common but hard-to-type document.getElementById(). (Recall from Chapter 2 that dollar signs and underscores are the two characters besides letters and numbers that are legal in JavaScript identifiers.)




JavaScript. The Definitive Guide
JavaScript: The Definitive Guide
ISBN: 0596101996
EAN: 2147483647
Year: 2004
Pages: 767

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