The Function object in JavaScript and also a discussion about functions in JS in general.
All JavaScript objects that are made with a constructor function (as opposed to ex nihilo) inherit from Function.prototype and hence inherit the properties and methods of function objects except for arguments (which is only available within functions) and .arity (which is deprecated anyway).
Function. A function is a defined sequence of statements (the function body) that does work and is usually invoked by calling upon it. In JS, functions are first-class functions, i.e. are objects that can be created, modified, manipulated, passed, assigned, etc., just like any other object. There are three ways to define a JavaScript function:
function FunctionName([Argument1 [, Argument2 [, ...ArgumentN]]]){FunctionBody}
A function statement/declaration is effectively a constructor and automatically makes a variable that is its own name. EG:
function dbl(n){return n+n};
alert(dbl(3)); //Returns 6
alert(dbl.toString()); //Returns definition
var fun=dbl;
alert(fun(3)); //Returns 6
alert(fun.name); //Returns dbl
function [FunctionName]([Argument1 [, Argument2 [, ...ArgumentN]]]){FunctionBody}
If named, the name can be used within the function body, especially if calling itself recursively. EG:
var fun=function dbl(n){return n+n};
alert(fun(3)); //Returns 6
alert(fun); //Returns definition
alert(dbl(3)); //Err
new Function ([strArgument1 [, strArgument2 [, ...strArgumentN]],]strFunctionBody)
Parameters. Zero or more (up to 255 in JS) arguments (parameters) are passed into the function when it is called upon. Non-object parameters (strings, numbers, and booleans) are passed in by value (a change in the paramter inside the function does not affect the value of the parameter outside of the function). Object parameters (objects, arrays, regular expressions) are passed in by reference (a change in the parameter inside the function affects the value of the parameter outside of the function). Excess parameters are ignored, while missing parameters are given the value of undefined.
Return. A function may return a value back to the location where the function was invoked. Since JS is loosely-typed, the type of the returned value may vary. In order for a function to return a value, the return [expression] statement must be used within the function. return will also stop execution of the function. If the return statement is not used, or return void(0) is used, then the function returns a value of undefined. The default value for constructors is this. A return statement is NOT white-space insensitive:
//This return returns the object
return {
MyObject }
//This return returns undefined!
return
{ MyObject }
Recursive. A recursive function is a function that calls itself. In JS, a recursive function has 3 ways to call itself: 1. The function's name. 2. arguments.callee(). 3. An in-scope variable that refers to the function. EG:
function WalkTree(node){
if (node==null) return;
for(var i=0; i<node.childNodes.length; i++){
WalkTree(node.childNodes[i]);
//arguments.callee(node.childNodes[i]); //alternative
}
}
Nesting and Closure. You can nest functions but the inner function is private to the outer function. When you call a function with an inner function, you can actually specify arguments for its inner function. EG: x = outerfun(varForOuter)(varForInner). If a reference to an inner function survives, then the outer function vars also survive.
Calling. While a function or method is usually called or run sort of like this: var x = AFunction();, it is also possible to use a function operator or expression to make an anonymous function which is immediately run by simply placing the parentheses next to it. EG: var y = function(){ return {a:1, b:'hi'}; }();. In the example if the last pair of parentheses were not there, the y would be the method, but intead with the parentheses, y is an object with two properties: a and b.
A few other examples of functions in JavaScript.
function double(a) { //A function statement that can be used directly
return a+a;
}
alert(double(2)); //Returns 4
function sayIt(){ //A function statement that is added as a method into objects below
return "I am " + this.name;
}
function Dog(name, breed) { //This function statement is a constructor for a Dog prototype
this.name = name; //Property of Dog
this.breed = breed; //Property of Dog
this.say = sayIt; //Method of Dog added via a object reference. Note the absence of parentheses.
this.bark = function() { //Method of Dog added via function operator. The function name is optional.
return "Bow Wow!";
}
}
myDog = new Dog("Spot", "Greyhound"); //This instantiates the object myDog
alert(myDog.say()); //Says "I am Spot"
alert(myDog.bark()); //Says "Bow Wow!"
myCat = {name:"Tom",say:sayIt}; On the fly object created using JSON
alert(myCat.say()); //Says "I am Tom"
Impremented:
JS 1.1;
JS 1.2 added arguments.callee;
JS 1.3 deprecated arguments.caller; removed support for argument names and local variable names as properties of the arguments object.
JS 1.4 deprecated arguments, arguments.callee, and arguments.length as properties of Function; retained arguments as a local variable of a function and arguments.callee and arguments.length as properties of this variable.
An array-like object corresponding to the arguments passed to a function. EG:
//Prior to JS 1.4: function fun(a, b, c) { alert(fun.arguments[0]); //alerts a } //JS 1.4+: function fun(a, b, c) { alert(arguments[0]); //alerts a }
Implemented: JS 1.2; JS 1.4 deprecated callee as a property of Function.arguments, retained it as a property of a function's local arguments variable.; ECMA-262.
Returns a reference to the currently executing function. Use arguments.callee within a function since Function.arguments.callee is deprecated.
//Allow an anonymous function to be recursive 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)
Implemented: JS 1.1; JS 1.3 deprecated; ECMA-262 not.
Like Function.prototype.caller which should be used instead.
Implemented: JS 1.1; JS 1.4 deprecated length as a property of Function.arguments, retained it as a property of a function's local arguments variable.
Returns the number of arguments actually passed to the function, as opposed to the number of arguments expected by the function (as per Function.length). Use arguments.length within a function since Function.arguments.length is deprecated.
function Add(x,y){
if (arguments.length == addNumbers.length) return (x+y);
else return null;
}
Implemented: JS 1.2; JS 1.4 deprecated in favor of Function.length
Specifies the number of arguments expected by the function.
Implemented: JS 1.5; ECMA-262 not.
Returns the function that invoked the specified function. Replaces the deprecated Function.arguments.caller. .caller returns null when the function is called from the top.
function myFunc() {
if (myFunc.caller == null) return ("The function was called from the top!");
else return ("This function's caller was " + myFunc.caller);
}
Implemented: JS 1.1; ECMA-262.
Returns a reference to the instance's function that created the instance's prototype. Contrast with .name which returns a string for the name of the function.
Implemented: JS 1.1; ECMA-262.
Returns the number of arguments expected by the function, as opposed to the number of arguments actually passed to the function (as per arguments.length). Array.length overrides so that it returns the number of elements in the array.
function Add(x,y){
if (arguments.length == addNumbers.length) return (x+y);
else return null;
}
[1,2,3].length==3; //true
Implemented: JS 1.5; ECMA-262 not.
The name of the function. Anonymous functions have empty string for name.
function myFun(){};
alert(myFun.name); //alerts 'myFun'
var f=function(){};
alert(f.name==''); //alerts true
var o={ fn: function(){} };
alert(o.fn.name==''); //alerts true
Implemented: JS 1.3; ECMA-262.
Allows you to apply a method of another object in the context of a different object (the calling object as specified by thisArg).
function otherObject(width) {
this.width=width;
}
function callingObject(width, height) {
this.height=height;
otherObject.apply(this, arguments);
}
callingObject.prototype = new otherObject()
var x = new callingObject(800, 600);
alert(x.width+" "+x.height);
Implemented: JS 1.3; ECMA-262.
Just like .apply except that .call uses a named set of parameters.
function otherObject(width) {
this.width=width;
}
function callingObject(width, height) {
this.height=height;
otherObject.call(this, width);
}
callingObject.prototype = new otherObject()
var x = new callingObject(800, 600);
alert(x.width+" "+x.height);
Page Modified: (Hand noted: 2008-03-17 22:30:42Z) (Auto noted: 2010-01-28 15:34:10Z)