Chapter 3. Functions

Variables are certainly an important part of any programming language; developers could not create efficient and meaningful applications without them. However, a language without any means of organizing code can lead to inefficient applications. In fact, some early programming languages, such as those used for punch cards (and languages based on them like RPG II), lacked organizational constructs, which resulted in many lines of repeated code.

Consider an application that performs the same series of operations on multiple variables. The following shows an example of such an application:

var valueOne = 100;
valueOne = valueOne + 150;
valueOne = valueOne / 2;
valueOne = "The value is: " + valueOne; // results in "The value is: 125"

var valueTwo = 50;
valueTwo = valueTwo + 150;
valueTwo = valueTwo / 2;
valueTwo = "The value is: " + valueTwo; // results in "The value is: 100"

var valueThree = 2;
valueThree = valueThree + 150;
valueThree = valueThree / 2;
valueThree = "The value is: " + valueThree; // results in "The value is: 76"

This is code duplication. The same operations are duplicated three times for three variables. Imagine having to repeat these same operations over and over again for as many variables as your program needs. Also imagine needing to change the addition operation (+ 150) to a subtraction operation (- 150). Not only would you have to make three changes with this code, but you'd also need to make the same change to any other variable that used the same pattern of statements. It's time-consuming and makes updates more prone to error.

Believe it or not, many older programming languages require this type of programming — typing statement after statement as many times as needed to perform the same set of operations for as many variables as needed. Not only is it time-consuming to create, but it's a nightmare to maintain when updates are required. This is the primary reason most programming languages today have functions.

Functions are arguably the most important part of any programming language. They encapsulate one or more statements to perform a certain task, and you can call, or execute, them whenever you want. But in JavaScript functions are exceptionally important because they have first-class status. In programming, first-class means that functions can be created on-the-fly, they can be stored in variables, and they can be passed as arguments to other functions. In other words, functions are a type of value in JavaScript, and this is a powerful feature that makes JavaScript one of the best languages to program with.

You've already been introduced to a few functions. The parseInt() and parseFloat() functions convert string values to numeric values. You've also seen a function called alert(), which displays information in an alert box in the browser. You know how to call functions and pass arguments to them, so now it's time to learn how to write your own functions.

FUNCTION DECLARATIONS

Functions are declared in function declaration statements by means of the function keyword. Unlike the statements seen in Lesson 2 and at the beginning of this lesson, function declaration statements do not end with a semicolon. The following code shows the syntax of a function declaration statement:

function functionName(parameter1, parameter2, etc) {
    // statements here
}

Function declaration statements begin with the function keyword, followed by a space and the function's identifier. The identifier should be unique throughout the entire HTML page, but at the same time it should be meaningful. For example, there's no guesswork as to what a function called sum() does; anyone reading the code can instantly recognize that the function adds two or more numbers together. Contrast that with a function named function4392(). Not even the person who wrote a function with that name would be able to remember what the function does. Readability is very important in writing code — especially when you're revisiting the code to make updates.

Function identifiers follow the same rules for identifiers outlined in Lesson 2:

  • The first character must be a letter, underscore, or dollar sign.

  • All other characters can be letters, numbers, underscores, or dollar signs.

  • An identifier cannot be the same as a keyword or reserved word.

After the identifier is a list of parameters separated by commas that are encapsulated within a pair of parentheses. Parameters are special variables that a function may need in order to properly do its work.

Note

You may hear and read the terms parameter and argument used interchangeably, but there is a distinction between them. The term parameter is more appropriately used to refer to an identifier between the parentheses in a function declaration. For example: "The function has three parameters." The term argument is more appropriately used to refer to a value passed to a function: "Pass the value 3 as an argument to the function."

Parameters are optional. Functions do not have to have them, but on the other hand, a function can accept multiple arguments. Regardless of the amount of parameters a function has, the opening and closing parentheses are required in the declaration. The following example shows the difference between a zero-parameter function and a function accepting two parameters:

function noArgumentFunction() {

}

function twoArgumentFunction(paraOne, anotherValue) {
    var newValue = paraOne + anotherValue;
}

The first function does not define any parameters due to the lack of any identifiers inside the parentheses. The second function, however, lists two parameters, and you can see how they are used within the function's body — just like variables.

After the parameter list is an opening curly brace. This marks the beginning of the function's body, and a closing curly brace marks the end. When called, the function executes the statements within its body. Any statements outside the function's body are not executed by the function.

Note

The function's body, or any amount of code occurring within a pair of curly braces, is sometimes referred to as a block of code.

Let's apply this information by modifying the code at the beginning of this lesson, and write a function to make the code easier to type and maintain. This function is called augmentValue(), and it accepts only one argument, called originalValue:

function augmentValue(originalValue) {
    var augmentedValue = originalValue;
    augmentedValue = augmentedValue + 150;
    augmentedValue = augmentedValue / 2;
    augmentedValue = "The value is: " + augmentedValue;

    return augmentedValue;
}

Compare the statements inside the function to the statements at the beginning of this lesson. The original value is stored within a variable and modified by the addition of 150, then divided in half, and finally converted into a string. With the exception of the last statement (the return statement), all statements in this function perform the same exact operations as the code listed at the beginning of this lesson. The only difference is the names of the variables.

The last line of the function uses the return keyword to exit the function and return the value stored within augmentedValue to the code that called the function. To use this function, simply call it by using its name, and pass a number value as an argument to the function (as with the parseInt() and parseFloat() functions in Lesson 2). The following code does just that:

var valueOne = augmentValue(100); // results in "The value is: 125"
var valueTwo = augmentValue(50);  // results in "The value is: 100"
var valueThree = augmentValue(2); // results in "The value is: 76"

When the function executes, the parameter originalValue contains the value passed to the function as an argument. So in the first line of this code, originalValue contains the value 100. When augmentValue() is called on the second line, originalValue contains 50, and in the final call to augmentValue(), originalValue is 2. The various operations are performed on each value, and the result is returned to the valueOne, valueTwo, and valueThree variables, respectively.

So isn't that easier? If you simply organize repetitive code into a function, the entire code is much easier to type, and maintenance becomes much simpler. Again, imagine that instead of adding 150 to the original value, you need to subtract 150 from it. In the old code you would have to make at least three changes and hope you don't forget to change the code anywhere else it's used. If you use a function, however, making that change is simple and easy because you have to make only one change to the function, and that one change is effective every time the function is called.

The use of functions is an example of code reuse as opposed to the code duplication seen at the beginning of this lesson. Instead of duplicating the same operations over and over again, you simply reuse one piece of code (the function) to get the same results. It makes application development and maintenance much easier.

It is not a requirement for functions to return a value; a function should return a value only if it needs to do so. In the case of augmentValue(), the function was written to replace code that resulted in a string value's being stored in a variable.

It's also important to note that functions immediately exit when they reach a return statement. Any statements following a return statement never execute. The following example rewrites the augmentValue() function to demonstrate this:

function augmentValue(originalValue) {
    var augmentedValue = originalValue;

    return augmentedValue;

    augmentedValue = augmentedValue + 150;
    augmentedValue = augmentedValue / 2;
    augmentedValue = "The value is: " + augmentedValue;
}

The bolded lines never execute in this version of augmentValue() because the function exits before those statements can execute. So, in effect, this function doesn't augment the original value at all; it simply returns the same value that is passed to the function.

Note

There are a few circumstances where code might execute after a return statement, but do not worry about that right now.

You can also use the return statement without specifying a value to return. Developers use this technique to exit a function early if it does not need to return a value.

FUNCTIONS AS VALUES

Using the function declaration statement isn't the only way to create a function; you can create an anonymous function. Anonymous functions, as the name suggests, don't have a name, and they are quite useful despite that fact.

Anonymous functions look very much like the function statements of the previous section. The only difference is the lack of an identifier, as the following example shows:

function(parmOne, parmTwo) {
    // statements here
}

On its own, this is actually invalid code because the interpreter expects a named function declaration, but what makes functions powerful in JavaScript is that they themselves are a type of value. This means that a function can be assigned to a variable, and doing so gives the function the name of the variable. Assigning a function to a variable is called using a function expression statement. Such a statement is a cross between the variable initialization statement and the function declaration statement. The following code rewrites the augmentValue() function using a function expression:

var augmentValue = function(originalValue) {
    var augmentedValue = originalValue;
    augmentedValue = augmentedValue + 150;
    augmentedValue = augmentedValue / 2;
    augmentedValue = "The value is: " + augmentedValue;

    return augmentedValue;
};

This code creates an anonymous function, complete with a parameter and its statements, and assigns it to the augmentValue variable. Notice the semicolon after the function's closing curly brace. Even though this statement involves the creation of a function, it is still an assignment operation, and as such should end with a semicolon.

You execute this function exactly like any other function, as follows:

var valueOne = augmentValue(100);

Other than how the function is created and named, there is virtually no difference between declared functions and functions assigned to variables. You execute them the same way, they execute the body of code the same way, and they exit the same way.

PASSING FUNCTIONS TO OTHER FUNCTIONS

Because functions are values in JavaScript, you can use them as you would any other value in the sense that they can be assigned to variables, passed to other functions, and returned by functions. You've seen one way of assigning a function to a variable by using a function expression statement, but it's also possible to assign a function declared with a function declaration statement to a variable. Look at this code:

function sum(paramOne, paramTwo) {
    return paramOne + paramTwo;
}

var sumCopy = sum;

This code creates a new function called sum(). It accepts two arguments and returns their sum. The last line of this code creates a variable called sumCopy, and it is assigned the sum() function. Pay careful attention to this assignment, and notice the identifier sum is used without the trailing set of parentheses. When you omit the parentheses after the name of a function, you use the function as an actual value.

So what this code does is create the sum() function, and then assign the actual sum() function to the sumCopy variable; sumCopy is now a function allowing you to use it exactly as you would sum(), like this:

var sumOne = sum(1, 2); // 3
var sumTwo = sumCopy(1, 2); // 3

The variable name sumCopy used in this example is actually misleading because it's not really a copy of sum() — it is sum() with a different identifier. Great, so you have a function with two different names! But why? Well, take a look at the following code:

function sum(paramOne, paramTwo) {
    return paramOne + paramTwo;
}

function multiply(paramOne, paramTwo) {
    return paramOne * paramTwo;
}

function calculate(paramOne, paramTwo, calculator) {
    return calculator(paramOne, paramTwo);
}

var sumResult = calculate(1, 2, sum); // 3
var multiplyResult = calculate(1, 2, multiply); // 2

This code creates three functions: sum(), multiply(), and calculate(). The first two functions are self-explanatory, but the third, calculate(), isn't so obvious. It accepts three arguments: two numeric values and a function value (calculator). In the body of calculate(), the function assigned to calculator is called and the two numeric values are passed to the function contained within calculator.

When the calculate() function is called in the final two lines of code, the sum() and multiply() functions are passed as the third argument. By passing sum() in the next-to-last line, the calculate() function calls sum(), passing it the numeric values of 1 and 2, and returns the result of sum() to the sumResult variable. In the last line multiply() is passed to calculate(). So calculate() calls multiply() and returns the result of calling multiply(1, 2).

Now look at another example:

var subtractionResult = calculate(1, 2, function(paramOne, paramTwo) {
    return paramOne - paramTwo;
}); // results in −1

This code uses the same philosophy as the code using sum() and multiply(), but an anonymous function is passed as the third argument to calculate(). This anonymous function subtracts the two values, resulting in a value of −1. So, you don't have to declare or name a function before you pass it as an argument to another function — it's usually sufficient to simply pass an anonymous function.

Code such as this is highly modular and flexible. Anytime you want to perform a mathematical operation on two numeric values, you can write a function to do it and pass it to the calculate() function to do the work for you. Granted, this particular example isn't all that useful, as you can directly call the sum() and multiply() functions without needing to call calculate(). But this technique of passing a function to another function is invaluable starting in Lesson 16, when you learn about events.

RETURNING FUNCTIONS

You can also return a function from a function as you would any other value. For example:

function someFunction() {
    return function() {
        alert("Hello!");
    };
}

var foo = someFunction(); // foo is now a function
foo(); // alerts the string "Hello!"

This code creates a function called someFunction(), and it returns an anonymous function to whatever called someFunction(). You can see this in the last two lines of this code. A variable called foo is assigned the return value of someFunction(), essentially making foo a function. Then, the foo() function is executed, alerting the text Hello! As in the previous section, the ability to return a function may not seem overly helpful. As you progress through the book, and especially in Lessons 20 and 23, you'll see many uses for returning a function from another function.

TRY IT

In this lesson, you learn about functions, how to write them, and how they are treated as values in JavaScript.

Lesson Requirements

For this lesson, you need a text editor; any plain text editor will do. For Microsoft Windows users, Notepad is available by default on your system or you can download Microsoft's free Visual Web Developer Express (www.microsoft.com/express/web/) or Web Matrix (www.asp.net/webmatrix/). Mac OS X users can use TextMate, which comes as part of OS X, or download a trial for Coda (www.panic.com/coda/). Linux users can use the built-in VIM.

You also need a modern web browser. Choose any of the following:

  • Internet Explorer 8+

  • Google Chrome

  • Firefox 3.5+

  • Apple Safari 4+

  • Opera 10+

Create a subfolder called Lesson03 in the JS24Hour folder you created in Lesson 1. Store the files you create in this lesson in the Lesson03 folder.

Step-by-Step

Write a function with two parameters: a first and last name. Have the function concatenate a greeting message using the two arguments, and return the greeting to the caller.

  1. Open your text editor and type the following code. Save the file as lesson03_example01.js.

    function getGreeting(firstName, lastName) {
        var greeting = "Hello, " + firstName + " " + lastName + "!";
    
        return greeting;
    }

    This code creates a function called getGreeting(). It accepts a first name and a last name as arguments, and it uses those values to create a greeting message that is stored in the greeting variable. Then the value contained within greeting is returned to the caller.

  2. Now call this function and alert the message by adding the following bolded code:

    function getGreeting(firstName, lastName) {
        var greeting = "Hello, " + firstName + " " + lastName + "!";
    
        return greeting;
    }
    
    var message = getGreeting("John", "Doe");
    alert(message);
  3. Resave the file.

  4. Open another instance of your text editor and type the following HTML:

    <html>
    <head>
        <title>Lesson 3: Example 01</title>
    </head>
    <body>
        <script type="text/javascript" src="lesson03_example01.js"></script>
    </body>
    </html>

    Save it as lesson03_example01.htm.

  5. Open the HTML file in your browser. You will see an alert box displaying the message Hello, John Doe!

Note

Please select Lesson 3 on the DVD to view the video that accompanies this lesson. You can also download the sample code for all lessons from the book's website at www.wrox.com.

Step-by-Step
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.89.18