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).

Basic Usage

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:

  • A function statement or declaration.
    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
    
  • A function operator or expression. Usually used inside an expression.
    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
    
  • A function constructor for the Function object. The Function constructor must be parsed everytime so it is slower than the other two ways.
    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"

Properties

.arguments (sort of)

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
}

arguments.callee

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)

arguments.caller

Implemented: JS 1.1; JS 1.3 deprecated; ECMA-262 not.
Like Function.prototype.caller which should be used instead.

arguments.length

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.

console.log((function () {}).length);  /* 0 */
console.log((function (a) {}).length); /* 1 */

.arity

Implemented: JS 1.2; JS 1.4 deprecated in favor of Function.length
Specifies the number of arguments expected by the function.

.caller

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);
}

.constructor

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.

.length

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

.name

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

Methods

.apply(thisArg, [argArray])

Implemented: JS 1.3; ECMA-262.
Allows you to invoke a method of one object in the context of a different object, or for having a different object (the "subclass") inherit a method from another object (the "superclass"), or both. The thisArg parameter is the different object that this will map to inside the function invoked. If thisArg is null or undefined, then the invoked function will assume that it is the global object.

function MySuper(name, width) {
    this.name = name;
    if (width > 800) {
        this.width = 800;
    } else {
        this.width = width;
    }
}
function MySub(name, width, height) {
    this.height = height;
    MySuper.apply(this, arguments);
}
MySub.prototype = new MySuper();
var x = new MySub("foo", 900, 900);
// x.height was set to 800

.call(thisArg[, arg1[, arg1[, ...]]])

Implemented: JS 1.3; ECMA-262.
Just like .apply except that .call uses a named set of parameters.

function MySuper(name, width) {
    this.name = name;
    if (width > 800) {
        this.width = 800;
    } else {
        this.width = width;
    }
}
function MySub(name, width, height) {
    this.height = height;
    MySuper.apply(this, name, width);
}
MySub.prototype = new MySuper();
var x = new MySub("foo", 900, 900);
// x.height was set to 800


GeorgeHernandez.comSome rights reserved