JavaScript Functions


In the first page of this tutorial we looked at the smallest elements of a program, the constants, variables, and operators, from which we made expressions, and touched on assignment statements. Then we looked at statements in general, and how to form them into larger structures. Now we will look at the largest structures, called functions, which form the basis of programs.

A function is a block of statements (enclosed in required braces) with a given name (identifier) and a list of variables called parameters which are given initial values separately determined, so that at any time in the running of the program this block can be called up to run with a specific values in those parameters, and possibly return a result value. Here is the form:

function name(param1, param2, ...) {statements}
The parameters are essentialy variable names used within the statements block, and which are given values when the function is called. There can be none or any number of them (within reason: the formal specification limits it to 255, but a dozen might be considered excessive).

That sounds abstract, let's look at a specific (but somewhat contrived) example. Suppose we had several pairs of numbers, and we wanted to display the sum, difference, and products of each pair on separate lines. We could tediously write:

var first = 5;
var second = 4;
var sum = first+second;
var difference = first - second;
var product = first * second;
document.write("<p>Sum of "+first+"+"+second+"="+sum
    + ", diff ="+difference+", product ="+product);
first = 3;
second = 7;
sum = first+second;
difference = second - first;
product = first * second;
document.write("<p>Sum of "+first+"+"+second+"="+sum
    + ", diff ="+difference+", product ="+product);
first = 2;
second = 2;
sum = first+second;
difference = first - second;
product = first * second;
document.write("<p>Sum of "+first+"+"+second+"="+sum
    + ", diff ="+difference+", product ="+product);
Or we could write a simple function to do the heavy lifting, then call it for each pair:
function ShowSumDifProd(first,second)
{
  var sum = first+second;
  var difference = first - second;
  if (first<second) difference = second - first;
  var product = first * second;
  document.write("Sum of "+first+"+"+second+"="+sum
      + ", diff ="+difference+", product ="+product);
}
Notice that the second pair reverses the difference (so it's always positive); we did that with a conditional. When you call a function, you give the name of the function, then enclose value expressions for each parameter in order, separated by commas, in parentheses, thus:
ShowSumDifProd(5,4);
ShowSumDifProd(3,7);
ShowSumDifProd(2,2);
The function can produce a value, which is returned to the caller in the return statement:
return expression;
If there is no value to return, but you want to return early (sort of like the break out of a loop), you can omit the expression:
return;
Let's add one more line to our function, so it returns the quotient:
function ShowSumDifProd(first,second)
{
  var sum = first+second;
  var difference = first - second;
  if (first<second) difference = second - first;
  var product = first * second;
  document.write("Sum of "+first+"+"+second+"="+sum
      + ", diff ="+difference+", product ="+product);
  return first / second;
}
Calling a function that returns a value has just that value returned, which can be combined with operators and/or used anywhere else a value is permitted, for example:
var quo = ShowSumDifProd(ShowSumDifProd(5,4),ShowSumDifProd(2,2));
In this example, the function is called for (5,4), which returns 1.25; then it is called for (2,2), returning 1. Finally it is called a third time with the previous two returned values now as parameters, returning 1.25 again. What happens if the second parameter is ever zero? Try it.
 

Recursion

One of the most powerful mathematical ideas is recursion, where a function calls itself. If you are not careful, it can get into an infinite loop of calling itself and never returning, so recursion always needs to express the choice of whether to return or call itself recursively in a conditional that must eventually be satisfied as a return, which is called the base case. The classic math problem solved by recursion is factorial, which is defined as 1 when evaluated for 0 (the base case), and for any other integer n as n multiplied times the factorial of (n-1). The function looks like this:
function fact(n) {if (n==0) return 1; else return fact(n-1)*n;}
What is the factorial of 5?

Recursion is a powerful software tool, but not many programmers understand it fully. The people who wrote the JavaScript are among those who do not, so there is a limit to recursion depth it allows. My browser crashed (sometimes killing the whole computer) when I tried 93 levels in this program:

var tops = 92;

function recurx(deep) {
  if (deep==0) return;
  if (deep%10 ==0) document.write("<br>"+deep);
    else document.write(" "+deep);
  recurx(deep-1);
  if (deep%10 ==0) document.write("<br>-"+deep);
    else document.write(" -"+deep);}

recurx(tops);

Releasing to the public a program that crashes is the mark of incompetence (or choosing C to program in, which amounts to the same thing). Experienced programmers know a variety of different ways to solve programming problems. Recursion is only one of them.

You can also have functions inside of functions in JavaScript, but it is not permitted in C++ nor Java, so we won't get into that.
 

Library

Functions are such a powerful tool that we often write functions to share with other programmers in collections called libraries. The most useful library comes with the language. They are called built-in functions, and every language has them. All the library functions are generally useful, and some of them turn out to be very difficult (or impossible) to write in JavaScript, so the language designer wrote them in a system language (like C) and secretly made them look like JavaScript functions, we don't need to know how. "Magic" is a technical word meaning "Happens by unspecified means."

Most of the built-in functions in JavaScript are associated with objects (which we will look at in the next page), but a few are stand-alone functions. One example is isNaN(value), which returns true if the parameter is not a number. Recall that we got "NaN" for non-numeric results earlier. NaNs are never equal to anything (not even themselves), so discovering you have one might be tricky, which makes this function useful.

Another useful JavaScript function is eval(text) which lets you execute a text string as if it were JavaScript code. This gives the language awesome power if you know how to use it. For the rest of us, it's still helpful in writing confusing code, like as a way to conceal email addresses on a web page (so they can be seen by people but hopefully not spider bots), or encrypting text for transmission over the internet.

Next: Data Structures

Tom Pittman
Rev 2010 December 22