JavaScript, Lesson 6 - Functions and Variable Scope

The Function Machine

Lesson Objectives

What is a function?

A function is a group of instructions which has been given its own particular name. It can be called at any point simply by quoting the name of the function (with a couple of brackets). Perhaps an example may be useful:

<script language="JavaScript">
var a = 1;
document.write("I shall now call the function.");
hereIsAFunction();
document.write("I can call it again!");
hereIsAFunction();
document.write("And yet again!");
hereIsAFunction();

function hereIsAFunction ()
{ a++;
  document.write(" The value of a is now : " + a + "<br />");
}
</script>

I have defined a function called hereIsAFunction and called it three times. The definition is at the end of the program (although it needn't be - you could put it at the beginning instead!) and starts with the word function, followed by the name and then a pair of brackets with nothing between them (I'll explain the purpose of those later). The two statements which actually make up the function (the instructions that the function actually carries out) are then enclosed within curly brackets. Please note that the brackets which come in the first line of the function definition do not have a semicolon after them.

The function is called simply by using its name followed by the two brackets and then, as usual, a semicolon. The output produced by the program is as follows:

I shall now call the function. The value of a is now : 2
I can call it again! The value of a is now : 3
And yet again! The value of a is now : 4

The function firstly adds 1 to the value of a and then displays the message together with the (new) value of a followed by a line break. You should also notice that there is no special instruction to tell the computer where the main part of the program ends and the function starts - the keyword function is enough to tell it that!

Here is another program. This one has two function definitions in it, and, just for a change, I have put them at the start of the program:

<script language="JavaScript">
function sum ()
{ answer = a + b + c;
}

function average ()
{ sum();
  averageValue = answer / 3;
}

var a = 34, b = 51, c = 60, answer, averageValue;
sum();
alert("The sum of the numbers is " + answer);
average();
alert("The average of the numbers is " + averageValue);
</script>

So what's going on here, then? Well, the first function adds three variables, a, b and c and stores the sum in a variable called answer. The second function calls the first function (you can call a function from within another function!) and then divides the variable answer by 3 to give the average of the three variables.

The main program creates the three variables with different values and then calls the sum() function. It displays the value of answer on the screen. Then it calls the average() function and displays the average value on the screen also. Neither function does any displaying on the screen itself, they just do calculations.

Parameters

The function sum() at the moment only adds the three variables a, b and c at the moment. In its present form, if you want it to add any other values you have to change the values of these variables. It would be nice if we could pass the values specifically to the function without having to set any variables as such. This is what parameters are for:

function sum (first, second, third)
{ answer = first + second + third;
}

var answer;
var first = 100, second = 23, b = 0, c = -44, temp = 750;
sum(1.4, -3, 16);
document.write("The sum is " + answer);
sum(b, 150, c + 4.2);
document.write("The new sum is " + answer);
sum(30 * c + 14, first, temp - second);
document.write("The even newer sum is " + answer);

This program extract is rather complicated, but it does illustrate the point nicely. Take a look at the function definition - this time there are three names inside those brackets, with commas between them. These are the parameter names - we are going to pass this function three items (numbers in this case) and we will refer to them as first, second and third inside the function. We can use these numbers just as if they were variables, you notice that we add them together inside the function just as if they were variables.

The parameters for the third function call When the function is called in the main program, it is given three numbers inside the brackets. These can be simple numbers, as in the case of sum(1.4, -3, 16), where the parameter first is set to the number 1.4, the parameter second is set to the number -3 and the parameter third is set to the number 16. Alternatively, they can be variable names or arithmetic expressions, as in the case of the other function calls. It is also true that the names of the parameters within the function have nothing to do with the names of variables (or anything else) in the outside program - you'll notice that in the third function call, I have actually passed across the value of a variable called first, but I have passed it as the second parameter value, so inside the function for that particular call, the parameter second will have the value 100, not the parameter first. Geddit?

The diagram on the right shows how the parameters in the third function call match the function definition itself:

Pass by value

The following program raises an interesting question. What happens to the value of temp?

<script language="JavaScript">
var temp = 40;
alert("The value of temp is " + temp);
doesTempChange(temp);
alert("The value of temp is " + temp);

function doesTempChange (temp)
{ temp *= 10;   // This multiplies temp by 10;
  document.write("Inside the function, temp is " + temp);
}
</script>

The variable temp is set to 40 and then passed to the function as a parameter. I have even called the parameter temp inside the function, although I didn't have to (it would still have worked even if I had called it sausage). The function multiplies temp by 10 and then displays its value. When the function has finished, the value of temp is displayed a third time.

So what does the program display? Well, since temp is set to 40, the first alert() instruction displays the value 40. The document.write() statement inside the function displays the value 400, since temp has been multiplied by 10. Again, no surprises there!

However, the second alert() statement, which executes after the function has finished, displays the number 40 again. Why is this? The reason is that any changes made to a parameter inside the function are not reflected back into the calling program - the value of the variable is merely copied when it is handed to the function. This has to be the case - for instance, if the function doesTempChange() were called like this:

doesTempChange(306);

... then how would the parameter value be changed?

The fact that parameter values are only ever passed into functions, never out of them, is sometimes referred to as Pass by value. We say that the parameter has scope which is local to the function.

Variable Scope

The variables that we have been using up to now have been global variables (they have global scope). This means that they existed throughout the whole of the JavaScript program. Indeed, you can declare them within one program block (enclosed within <script language="JavaScript"> ... </script> tags) and they can easily be used within another program block.

However, it is different for parameters and variables declared within functions. Consider this program:

<script language="JavaScript">
function sillyFunc ()
{ var a = 5000;
  document.write("Inside the function, a = " + a + "<br />");
}

var a = 10;
document.write("Before the call, a is " + a + "<br />");
sillyFunc();
document.write("After the call, a is " + a + "<br />");
</script>

This displays the following output:

Before the call, a is 10
Inside the function, a = 5000
After the call, a is 10

You will notice that the variable a declared within the function appears to have nothing to do with the variable a declared in the main program. It is set to 5000 (as proved by the statement displaying its value) but when the function has finished, the variable inside the function has disappeared and we are back to the original variable a with its original value of 10.

The local variable only exists during the function call. While the function is executing, the global variable a (the one with the value 10 in the outside program) is shut away and can't be accessed. Instead, the local version takes over. When the function finishes, the local variable dies and the global one is released and becomes active again. Now we change the program ever so slightly:

<script language="JavaScript">
function sillyFunc ()
{ a = 5000;
  document.write("Inside the function, a = " + a + "<BR>");
}

var a = 10;
document.write("Before the call, a is " + a + "<BR>");
sillyFunc();
document.write("After the call, a is " + a + "<BR>");
</SCRIPT>

All I have done is take out the word var from the function definition. This means that there is no local version of the variable a, and setting a to any value within the function will have a permanent change on it. In this case, the output is:

Before the call, a is 10
Inside the function, a = 5000
After the call, a is 5000

This time the value has changed. There is only one variable called a, the global one. The question of whether a variable is local or global only arises if a function contains a variable declaration with the same name as a variable in the outside program.

The return statement

The return instruction only ever appears inside functions. It is used to pass values out of the function and back to the main program which called it (or to a calling function if it was called from another function). The return instruction is followed by the value to be returned, and it means that the function call can be used in place of a number or string. Perhaps an example will make all this clear:

<script language="JavaScript">
function average (num1, num2, num3, num4)
{ var sum = num1 + num2 + num3 + num4;
  return sum / 4;
  alert("Yah boo sucks!");
}

var a = 2, b = 30, c = 78, x = 100;
document.write("The average is " + average(a, b, c, x) + "<BR>");
</script>

Look at the function call first. You will notice that it is has been put in place of a number or variable. We could just as easily have made the instruction

document.write("The average is 52.5<br />");

as the function average(a, b, c, x) "hands back" the number 52.5. The value to be handed back is sum / 4 as that is the expression that comes after the return statement. The variable sum is a local variable to the function and dies as soon as the function finishes, but its memory lives on as a quarter of its value is given to the main program.

Whenever a function reaches a return statement the function finishes. Any other statements that come after it are ignored. This means that the alert("Yah boo sucks!") statement is never executed and the message never appears on the screen (fortunately!) Normally you wouldn't bother to put statements after a return statement in the function (it would be the last statement in the function), but I did in this case in order to demonstrate that the return statement finishes the function.

In the sample program below, I have rewritten a program from above using parameters and return. Compare it with the original, and you will see that this version is a lot more compact:

<script language="JavaScript">
function sum (a,b,c)
{ return a + b + c;
}

function average (a,b,c)
{ return sum(a,b,c) / 3;
}

var a = 34, b = 51, c = 60;
alert("The sum of the numbers is " + sum(a,b,c));
alert("The average of the numbers is " + average(a,b,c));
</script>

Recursive Functions

As you have seen above, it is possible for a function to call another function. It is equally possible for a function to call itself. Such a function is called a recursive function. Let's take an example - the example they always use - is factorial numbers.

Factorials are written using the ! symbol, and are defined as follows:

0! = 1 (by definition)
1! = 1
2! = 2 x 1 = 2
3! = 3 x 2 x 1 = 6
4! = 4 x 3 x 2 x 1 = 24
5! = 5 x 4 x 3 x 2 x 1 = 120

Get the idea? You will notice that a quick way to get any factorial is to multiply the number by the previous factorial, e.g. 5! = 5 x 4! Similarly, 9! = 9 x 8! and 103! = 103 x 102! This means that if you know a factorial you can easily get the next one in the series. Here we have the same idea as a function:

<script language="JavaScript">
function factorial (n)
{ if (n == 0)
   return 1;
  else
   return n * factorial(n-1);
}

// Display all the factorials from 0! to 10!
var count;
for (count = 0; count < 11; count++)
 document.write("The factorial of " + count + " is " +
                 factorial(count) + "<BR>");
</script>

The function takes a parameter and calculates the factorial of that number. Note that the first thing that the function does is test to see if we have reached the lowest number for which factorial is defined. This is the stopping condition of the recursive function and all recursive functions must have one. Suppose it had been missed out:

function factorial (n)
{ return n * factorial(n-1);
}

Such a function, when called, would never terminate as it would endlessly be calling itself.