The Function object in JavaScript and also a discussion about functions in JS in general.
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 only be used within the function body. 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 pparameter outside of the function).
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 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. You can nest functions but the inner function is private to the outer function. One quirk is that when you call a function with an inner function, you can actually specify arguments for its inner function. EG: x = outerfun(varForOuter)(varForInner).
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 epxression 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"
arguments. An array corresponding to the arguments passed to a function. EG: The first argument could be accessed via arguments[0]. The arguments array is only available within the body of the function (note the lack of the .). The arguments array also has the following properties:arguments.callee. Returns a string containing the current function's constructor.arguments.caller. Returns the name of the function that called the current function, or null if called from the top level of the JavaScript program.arguments.length. The number of arguments actually passed to the function. A function may receive more arguments than its arity..arity. Specifies the number of arguments expected by the function. Deprecated: use .length instead..caller.constructor. Specifies the function that creates an object's prototype. Note that the value of this property is a reference to the function itself, not a string containing the function's name..length. Specifies the number of arguments expected by the function.
.name. Specifies the name of the function..prototype. Any object which has a constructor function has a .prototype property/object. .prototype enables class extensions, i.e. the addition of more properties or methods to the class beyond that defined by the constructor function. If you add a property to the prototype for an object, then all objects created with that object's constructor function will have that new property, even if the objects existed before you created the new property. Of course properties and methods can be added directly to individual objects instead of the whole class; this is known as instance extension. EG:
function book(author){
this.title = title;
this.author = author
}
var myBook = new book("Asimov");
myBook.title = "Foundation";
//Now add new members to old and future objects.
function say(){
document.write("Book's genre is: " + this.genre);
}
book.prototype.genre = null;
book.prototype.say = say;
book1.genre = "SF";
book1.say();
//In contrast, the next property is added only to the current object
book1.rating = "Excellent";
These methods are inherited from Function.prototype: .apply(), .call(), .toSource(), .toString(), .valueOf().
.apply(thisArg[, argArray]). (Read the .call() method first.) Allows you to apply a method of another object in the context of a different object (the calling object). The calling object thus inherits the method from the other object. Clearly it is almost always easier to use the .apply() method than the .call() method since the former is easier to extend with because of the arguments property.function bat(b1,b2,b3,c1,c2,c3,r1,r2,r3){
this.b1=b1; this.b2=b2; this.b3=b3;
}
function cat(b1,b2,b3,c1,c2,c3,r1,r2,r3){
this.c1=c1; this.c2=c2; this.c3=c3;
}
function rat(b1,b2,b3,c1,c2,c3,r1,r2,r3){
this.r1=r1; this.r2=r2; this.r3=r3;
}
function xat(b1,b2,b3,c1,c2,c3,r1,r2,r3){
bat.apply(this,arguments);
cat.apply(this,arguments);
rat.apply(this,arguments);
}
at1 = new xat(1,1,1,3,3,3,5,5,5);
document.write(xat.b1+" "+xat.c2+" "+xat.r3);
.call(thisArg[, arg1[, arg2[, ...]]]). Allows you to call (execute) a method of another object in the context of a different object (the calling object). The calling object thus inherits the method from the other object. (See also the .apply() method.)function bat(b1,b2,b3,c1,c2,c3,r1,r2,r3){
this.b1=b1; this.b2=b2; this.b3=b3;
}
function cat(b1,b2,b3,c1,c2,c3,r1,r2,r3){
this.c1=c1; this.c2=c2; this.c3=c3;
}
function rat(b1,b2,b3,c1,c2,c3,r1,r2,r3){
bat.call(this,b1,b2,b3);
cat.call(this,c1,c2,c3);
this.r1=r1; this.r2=r2; this.r3=r3;
}
at2 = new rat(1,1,1,3,3,3,5,5,5);
.toSource(). Returns a string representing the source code of the function. Overrides the Object.toSource() method.
.toString(). Returns a string representing the source code of the function. Overrides the Object.toString() method.
.valueOf(). Returns a string representing the source code of the function. Overrides the Object.valueOf() method.
These methods are inherited from Object.prototype: __defineGetter__(), __defineSetter__(), hasOwnProperty(), isPrototypeOf(), __lookupGetter__(), __lookupSetter__(), __noSuchMethod__(), propertyIsEnumerable(), unwatch(), watch().
These are top level functions that are built into JavaScript and are not associated with any objects.
These functions are most often used for data going to or from an URL, URI, query string, etc..
decodeURI(encodedURI). JS 1.5.decodeURIComponent(encodedURIComponent). JS 1.5.encodeURI(URI).
/ ? : @ & = + $ ,. ECMAS considers ; as a URI reserved character, but JS does not consider.A-Z, a-z, 0-9.- _ . ! ~ * ' ( ).#.%XX where X is a hexadecimal digit.%XX, %XX%XX, or %XX%XX%XX.%XX, %XX%XX, %XX%XX%XX, or %XX%XX%XX%XX.encodeURIComponent(URIComponent).
A-Z, a-z, 0-9, - _ . ! ~ * ' ( ).#.escape(URI).
A-Z, a-z, 0-9.- _ . * @ + /.%XX where X is a hexadecimal digit. This implies that it only handles a subset of Unicode characters.Server.URLEncode() method of ASP, and the Escape() function of VBS.unescape(escapedURI).
Unescape() function. ASP does not have an equivalent method.eval(string).
str = "3 * x + 4"
x = 2
myValue = eval(str)
/*myValue is equal to 10. You could have done any number of things to get the value of 10.*/
var thisImg = eval("img" + strImageName)
thisImg.src = strURL
isFinite(number). Checks if a value is a finite number. If the number is NaN, positive infinity or negative infinity, then this method returns false, otherwise it returns true. JS 1.3+.isNaN(value). Checks if value is NaN. JS 1.0+.Number(object). Converts an object to a number. If the object does not contain a well-formed numeric literal, Number returns NaN. JS 1.2+.parseFloat(string). Converts string to floating-point number. JS 1.0+.parseInt(string[,radix]).
String(object). Converts the object to a literal string. JS 1.2+.taint(). Taints or marks a data element or script. JS 1.3 last.untaint(). Removes tainting from a data element or script. JS 1.3 last.As a side, here are the Top-Level Properties:
Infinity. JS 1.3+ (previously Number.Infinity).NaN. Not-A-Number. JS 1.3+ (previously Number.NaN).undefined. JS 1.3+.2008-03-17 22:30:42Z