A function that does not return a value returns undefined.
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Functions
http://jibbering.com/faq/faq_notes/closures.html
--------------------------------------------------------------------------------
Non-object parameters, e.g. strings, numbers and booleans, are passed to
functions by value; the value is passed to the function where it is stored
in a new variable. If the function changes the value of the variable, this
change is not reflected globally or in the calling function. Object parameters,
e.g. objects, arrays and regular expressions, are passed to functions by
reference; if you pass an object as a parameter to a function and the function
changes the object's properties, that change is visible outside the function,
as shown in the following example:
function myFunc(theObject) {
theObject.brand = "Toyota";
}
var mycar = {brand: "Honda", model: "Accord", year: 1998};
alert(mycar.brand); // shows 'Honda'
myFunc(mycar); // pass object mycar to the function
alert(mycar.brand); // shows 'Toyota' as the brand property of
// mycar was changed by the function)
--------------------------------------------------------------------------------
The this keyword does not refer to the currently executing function, so you must
refer to Function objects by name, even within the function body. Alternatively,
you can use the arguments.callee property. arguments.callee allows anonymous
functions to refer to themselves, which is necessary for recursive anonymous
functions.
JavaScript 1.2
JavaScript 1.4: Deprecated callee as a property of Function.arguments, retained
it as a property of a function's local arguments variable.
Example: Using arguments.callee in an anonymous recursive function
A recursive function must be able to refer to itself. Typically, a function
refers to itself by its name. However, an anonymous function does not have a
name, and if there is no accessible variable referring to it, i.e. the function
is not assigned to any variable, the function cannot refer to itself. (Anonymous
functions can be created by a function expression or the Function constructor.)
This is where arguments.callee comes in.
The following example defines a function, which, in turn, defines and returns a
factorial function.
function makeFactorialFunc() {
alert('making a factorial function!');
return function(x) {
if (x <= 1)
return 1;
return x * arguments.callee(x - 1);
};
}
var result = makeFactorialFunc()(5); // returns 120 (5 * 4 * 3 * 2 * 1)
Anonymous or Unnamed Functions
The following example defines an unnamed function and assigns it to x. The
function returns the square of its argument:
var x = function(y) {
return y * y;
};
The next example declares array a as an array of three functions:
var a = [
function(y) {
return y;
}
,
function(y) {
{
return y * y;
}
,
function (y) {
return y * y * y;
}
];
For this array, a[0](5) returns 5, a[1](5) returns 25, and a[2](5) returns 125.
--------------------------------------------------------------------------------
Recursion
The following loop can be converted to a recursive function
var x = 0;
while (x < 10) { // "x < 10" is the loop condition
// do stuff
x++;
}
As follows:
function loop(x) {
if (x >= 10) // exit condition (equivalent to "!(x < 10)")
return;
// do stuff
loop(x + 1); // the recursive call
}
loop(0);
However, some algorithms cannot be simple iterative loops. For example, getting
all the nodes of a tree structure (e.g. the DOM) is more easily done using
recursion:
function walkTree(node) {
if (node==null)
return;
// do something with node
for (var i = 0; i < node.childNodes.length; i++) {
walkTree(node.childNodes[i]);
}
}
Demonstration of how a recursive function uses a Function() Stack
function foo(i) {
if (i < 0)
return;
document.writeln('begin:' + i);
foo(i - 1);
document.writeln('end:' + i);
}
foo(3);
--------------------------------------------------------------------------------
Nested Functions
http://developer.mozilla.org/en/docs/
Core_JavaScript_1.5_Reference:Functions#Nested_functions_and_closures
http://jibbering.com/faq/faq_notes/closures.html
You can nest a function within a function. The nested (inner) function is
private to its containing (outer) function. It also forms a closure.
A closure is an expression (typically a function) that can have free variables
together with an environment that binds those variables (that "closes" the
expression). Since a nested function is a closure, this means that a nested
function can "inherit" the arguments and variables of its containing function.
In other words, the inner function contains the scope of the outer function.
The inner function can be accessed only from statements in the outer function.
The inner function forms a closure: the inner function can use the arguments and
variables of the outer function, while the outer function cannot use the
arguments and variables of the inner function.
The following example shows nested functions:
function addSquares(a,b) {
function square(x) {
return x * x;
}
return square(a) + square(b);
}
a = addSquares(2,3); // returns 13
b = addSquares(3,4); // returns 25
c = addSquares(4,5); // returns 41
Since the inner function forms a closure, you can call the outer function and
specify arguments for both the outer and inner function:
function outside(x) {
function inside(y) {
return x + y;
}
return inside;
}
result = outside(3)(5); // returns 8
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------