Functions

Functions allow useful bits of code to be bundled up into a block and given a name so that the bundle can be referred to by its name each time it's required, rather than being re-typed. The syntax for making a function is:

function name(arguments)
{
    statements, possibly including 'return'
}

and for referring to an existing function:

name(argument-values);

function is a JavaScript keyword like var or while. Name is the unique name given to the function, which follows the rules for variable names. Return is a keyword similar to break, which can only exist inside the function. 'Arguments' is an optional comma-separated list of variables which will be used inside the function, and are similar to the data that the expression operators work with. 'Argument-values' is a comma-separated list of data items to be used by the function when it's referred to. Three examples:

function say_hello()
{
    document.write('Hello. ');
    document.write('Welcome to the say_hello() function. ');
    return;
}

function add_together(first, second)
{
    var result = first + second;
    return result;
}

function add_all()
{
    var loop=0, sum=0;
    for ( loop = arguments.length-1; loop >=0; loop--)
        sum += arguments[loop];
    return sum;
}

// Now make them happen

say_hello();
var answer = add_together(5, 3);
document.write( answer + ' ' + add_together(10, 4) );
document.write( ' ' + add_all(1, 3, 5, 7, 9) );

As you can see, most of the effort is in declaring the functions, that is, making the JavaScript interpreter aware they exist. This is equivalent to the var statement for variables. Only the last four lines make them "go". This script fragment displays this output:

Hello. Welcome to the say_hello() function. 8 14 25

A bit of terminology can go a long way toward speaking intelligently about functions. When a function is made to happen, it's said to be called or invoked from the piece of script that refers to it. Data specified between the parentheses when the function is called are known as arguments or parameters and are said to be passed to the function. When a function has a value to hand back to the place it was called from, it is said to return that value.

There are several things going on in this example. Firstly, return is being used in two ways. If there's an answer to be handed back from a function, return hands it back. Otherwise, return returns undefined. Secondly, sometimes functions have arguments declared, as for add_together(). Once the function is running, these act just like normal variables, except that they are unavailable outside the function, a bit like break is unusable outside a for or while loop. Thirdly, even if no arguments are declared, a function can still get at any that are passed to it, as shown in add_all(). In this function, no arguments are declared but clearly 5 are passed to it (in the last line). Inside every function is a special Array called arguments (it's always present), that can be examined for the number and values of the arguments passed in. This allows a function to handle the less common case where it is passed different numbers of arguments at different times.

Finally, the last two functions have some variable declarations in them—loop, sum and result. These are not accessible outside the function they appear in, but they're not special like the arguments Array. They are an example of scoping. Scoping means variables are only present in a limited part of the program, to reduce complexity. The rule is that any variable is useable until a close-bracket ('}') appears which matches the nearest open bracket ('{') BEFORE the spot where the variable first appeared. If that was all, then complexity would indeed be reduced, but the scoping rules also say that its possible to have more than one variable with the same name—if so, the one in the innermost (meaning nearest) scope will be used. An example that shows scoping at work is:

var stuff = 'outside';

function do_it()
{
    var stuff = 'inside';
    document.write(stuff);
}

document.write(stuff);            // display 'outside'
do_it();                  // display 'inside'

New scopes aren't created inside if branches or in while or for statement blocks. Those kinds of blocks will obey whatever scopes were at work just before they began, however. Only functions produce new scopes.

Earlier, there was some discussion of operators that have side effects in expressions and conditions, such as the pre-increment operator ('++'). The main purpose of expressions and conditions is to return a value that is the result of calculating the expression or condition. Functions can do anything when called, including performing statements that are unrelated to the return value that they pass back. Since functions can participate in expressions and conditions, quite powerful side-effects can occur as this optimistic example shows:

var tasks_complete = solve_all_world_problems() + keep_everyone_happy();

Whatever the statements in these functions are, it's likely they are large and complex ...

JavaScript comes with a few generally useful ECMAScript native functions. See the Reference Section for the gory details. These are parseInt(), parseFloat(), escape(), unescape(), isNaN(), isFinite() and eval(). All of these are for String and Number manipulation, except eval() which is special.

IsNaN() doesn't do much on Internet Explorer 3.02 with JScript 1.0, since NaNs are unknown there.

The function eval() takes a string, examining and running it as though it was a JavaScript scriptlet. This lets the script writer get a string from somewhere else (for example from user input) and run it straight away without starting any new program. This is a very powerful feature, but it also can let the user do all kinds of damage to any variables and functions you have in the JavaScript that lets this happen.

var code = 'x + y';
var x = 5, y = 4;
document.write( eval(code) );               // displays 9

© 1997 by Wrox Press. All rights reserved.