Functions
Functions
- call functions
- create functions
- explain global and local variable scope
- write anonymous functions
- explain the difference between passing arguments by value and by reference
- create a function which handles a variable number of arguments
- create an immediately invoked function
- use nested functions
- create recursive functions
Overview
- Functions are great for encapsulating code for reuse.
- Functions help modularize code, which makes applications easier to develop,
write, read, and maintain.
- Functions are objects in JavaScript.
- General purpose functions can be packaged into libraries which
can then be easily reused.
Defining a function
- A sample template for a function is given below.
- The function name is not required if you are assigning the
function to a variable or passing it as an argument.
- Functions without a name are called anonymous functions.
- The parameter list is a comma separated list of valid identifier names.
- The parameter variables are only visible within the function.
- The parameter list is optional, has no type checking, and doesn't even have to
match the number of arguments that are used when the function
is called.
- You may choose to return one item of data or not return
anything. Since JavaScript deals with objects easily, the one
item of data returned could be an object or array containing many
individual items.
- Any variables used only within the function should be declared
within the function using the "var" keyword to make sure they aren't
confused with global variables.
function functionName(parameterList) {
// function body - code that does the work goes here
return data; // optional
}
Calling a function
- template: functionName(argumentList);
- The argument list is a comma separated list of variable
names or values. You may skip an argument in the list by using
the value "undefined" for it. The argument list is optional and
the number of arguments sent does not have to match the number
of parameters specified in the function definition.
- Arguments which are basic variable types (string, number, Boolean)
are sent to the function by-value. This means that copies of the
value are sent and the original variable can not be changed by
the function.
- Arguments which are not basic variable types (such as objects and arrays)
are sent to the function by-reference. This means that the original
variable can be changed by the function.
- The names of the arguments sent and the paramters received does not
have to match.
- Since the number of parameters doesn't have to match the number of
arguments sent, every function has a list of the arguments sent to
it stored in an array-like object named "arguments". This allows
functions to easily handle variable length argument lists.
// example of passing-by-value
function test(x) {
x = 2 * x;
console.log(x); // displays: 2 * what was passed in
}
var x = 3;
console.log(x); // displays: 3
test(x); // will display 6 inside test
console.log(x); // displays: 3 (x was not modified)
// example of passing-by-reference
function test2(obj) {
obj.x = 2 * obj.x;
console.log(obj.x);
}
var obj = { x: 3 };
console.log(obj.x); // displays: 3
test2(obj); // will display 6 inside test
console.log(obj.x); // displays: 6 (x was modified)
// example of handling a variable number of arguments
function add() {
var sum = 0;
for (var i=0,count=arguments.length; i<count; i++) {
if (! (typeof arguments[i] == 'number')) {
sum = 0;
break;
}
sum += arguments[i];
}
return sum;
}
console.log(add()); // displays: 0
console.log(add(5, 3)); // displays: 8
console.log(add(5, "Hi", 3)); // displays: 0
console.log(add(1,2,3,4,5,6,7,8,9,10)); // displays: 55
console.log(add("15")); // displays: 0
Anonymous, nested, and immediately invoked functions
- Anonymous functions have no names. If they have no names, how can
they be used? It can be used by:
- assigning it to a variable
- assigning it as the value of an object property
- passing it as an argument to a function
- immediately invoking it
- A nested function is simply one function defined inside another
function. This makes the nested function invisible to code outside
of the function it is nested inside.
- An immediately invoked function is a function which is run
as soon as it is defined. Everything in the immediately invoked
function is hidden from other code.
// example of an anonymous function used to handle an event
// The window's background color is changed when the user clicks in the window
window.onclick = function() { document.body.style.backgroundColor = "#0000ff"; };
// example of an anonymous function assigned to a variable
var cube = function(x) { return x * x * x; };
console.log(cube(2)); // displays: 8
console.log(cube(3)); // displays: 27
// example of an anonymous function assigned to an object property
var obj = {
nm: "Humanoid",
greet: function() { alert("Greetings " + this.nm); }
};
obj.greet(); // displays: Greetings Humanoid
// example of a nested function
// Note: this function does NO error checking of the argument
function sumOfSquares(arr) {
// function sq can't be seen outside sumOfSquares
function sq(x) { return x*x; }
var sum=0;
for (var i=0; i<arr.length; i++) sum += sq(arr[i]);
return sum;
}
console.log(sumOfSquares([3,4])); // displays: 25
// example of an immediately invoked function
// nothing in the function can be seen outside the function
(function() {
var abc=5;
console.log(abc);
})();
// displays: 5
Recursive functions
- Recursive functions are those that call themselves either directly or indirectly.
- You can always replace recursion with iteration and often save resources (time, memory).
- Recursion is often easier to read, write, and understand (once you get used to the
idea of how recursion works).
- Recursive functions must alwasy lead eventually to a simpler base case so the recursion ends.
// Computing a factorial is a common recursion example
// The factorial of a positive integer N (written N!) is defined
// as N! = N * (N-1) * (N-2) * ... * 1
// Note that this means 5! = 5 * 4!, 3! = 3 * 2!, etc.
//
// A recursive definition is:
// 0! = 1
// 1! = 1
// N! = N * (N-1)! // where N > 1
function fac(n) { return n<2 ? n : n * fac(n-1); }
fac(3); // returns: 6
fac(4); // returns: 24
fac(5); // returns: 120
Exploring recursion
Try to write recursive JavaScript functions for these other commonly used
icons of recursion:
- Fibonacci numbers
- Reversing a string
- Checking to see if a string is a palindrome
- Towers of Hanoi