loading...

JavaScript – Defining Functions

Functions are defined with the function keyword, which can be used in a
function definition expression (Function Definition Expressions) or
in a function declaration statement (function). In either form, function definitions
begin with the keyword function
followed by these components:

  • An identifier that names the function. The name is a
    required part of function declaration statements: it is used as
    the name of a variable, and the newly defined function object is
    assigned to the variable. For function definition expressions, the
    name is optional: if present, the name refers to the function
    object only within the body of the function itself.

  • A pair of parentheses around a comma-separated list of zero
    or more identifiers. These identifiers are the parameter names for
    the function, and they behave like local variables within the body
    of the function.

  • A pair of curly braces with zero or more JavaScript
    statements inside. These statements are the body of the function:
    they are executed whenever the function is invoked.

Example 8-1 shows some function
definitions using both statement and expression forms. Notice that a
function defined as an expression is only useful if it is part of a
larger expression, such as an assignment or invocation, that does
something with the newly defined function.

Example 8-1. Defining JavaScript functions

// Print the name and value of each property of o.  Return undefined.
function printprops(o) {
    for(var p in o) 
        console.log(p + ": " + o[p] + "\n"); 
}

// Compute the distance between Cartesian points (x1,y1) and (x2,y2).
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);
}

// This function expression defines a function that squares its argument.
// Note that we assign it to a variable
var square = function(x) { return x*x; }

// Function expressions can include names, which is useful for recursion.
var f = function fact(x) { if (x <= 1) return 1; else return x*fact(x-1); };

// Function expressions can also be used as arguments to other functions:
data.sort(function(a,b) { return a-b; });

// Function expressions are sometimes defined and immediately invoked:
var tensquared = (function(x) {return x*x;}(10));

Note that the function name is optional for functions defined as
expressions. A function declaration statement actually
declares a variable and assigns a function object
to it. A function definition expression, on the other hand, does not
declare a variable. A name is allowed for functions, like the
factorial function above, that need to refer to themselves. If a
function definition expression includes a name, the local function
scope for that function will include a binding of that name to the
function object. In effect, the function name becomes a local variable
within the function. Most functions defined as expressions do not need
names, which makes their definition more compact. Function definition
expressions are particularly well suited for functions that are used
only once, as in the last two examples above.

Function Names

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 (and not part of a public API) 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
jQuery (covered in Chapter 19), for example, makes
heavy use in its public API of a function named $() (yes, just the dollar sign). (Recall
from Identifiers and Reserved Words that dollar signs and
underscores are the two characters besides letters and numbers that
are legal in JavaScript identifiers.)

As described in function, function
declaration statements are “hoisted” to the top of the enclosing
script or the enclosing function, so that functions declared in this
way may be invoked from code that appears before they are defined.
This is not true for functions defined as expressions, however: in
order to invoke a function, you must be able to refer to it, and you
can’t refer to a function defined as an expression until it is
assigned to a variable. Variable declarations are hoisted (see Function Scope and Hoisting), but assignments to those variables are
not hoisted, so functions defined with expressions cannot be invoked
before they are defined.

Notice that most, but not all, of the functions in Example 8-1 contain a return statement (return). The return
statement 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.

Most of the functions in Example 8-1 are
designed to compute a value, and they use return to return that value to their caller.
The printprops() function is
different: its job is to output the names and values of an object’s
properties. No return value is necessary, and the function does not
include a return statement. The
value of an invocation of the printprops() function is always undefined. (Functions with no return value
are sometimes called procedures.)

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));
}

The interesting thing about nested functions is their variable
scoping rules: they can access the parameters and variables of the
function (or functions) they are nested within. In the code above,
for example, the inner function square() can read and write the parameters
a and b defined by the outer function hypotenuse(). These scope rules for nested
functions are very important, and we’ll consider them again in Closures.

As noted in function, function
declaration statements are not true statements, and the ECMAScript
specification only allows them as top-level statements. They can
appear in global code, or within other functions, but they cannot
appear inside of loops, conditionals, or try/catch/finally or with statements.[10] Note that this restriction applies only to functions
declared as statements. Function definition expressions may appear
anywhere in your JavaScript code.


[10] Some JavaScript implementations relax this rule. Firefox,
for example, allows “conditional function declarations” that
appear within if
statements.

Comments are closed.

loading...