Javascript Functions

0

Category :

Functions in JavaScript let you define code that is called on demand, instead of immediately. There are several ways to define a function:

Function Declaration

standard function statement
  • must always have an Identifier(function name).
  • parsed and evaluated before any other expressions are. Even if declaration is positioned last in a source, it will be evaluated before any other expressions contained in a scope.

function getarea(w,h){
 //standard function
 return w * h;
}

getarea(3,5) //calls function

Function Literal or Expression

an anonymous function assigned to a variable
var getarea = function(w,h){
 return w * h;
}

getarea(3,5) //calls function

Function Expression may omit Identifier.
Named Function Expressions may only access its Identifier in the scope of its newly-defined function
Named Function Expressions make for a much more pleasant debugging experience.

Function Constructor

creates a function on the fly, which is slower and generally discouraged
//syntax: new Function(argument1, argument2, ..., argumentY, functionbody) 
//all parameters must be a string

var getarea=new Function("w", "h", "var area=w*h; return area")
getarea(3,5) //calls function



What's the difference between declaration and expression?

The 'identifier' is optional for function expression. And when you don't give an identifier, you create an anonymous function. It doesn't mean that you can't specify an identifier.
This means following is valid.
var sum = function mySum(a, b) { return a + b; }
Important point to note is that you can use 'mySum' only inside the mySum function body, not outside. See following example:
var test1 = function test2() { alert(typeof test2); }

alert(typeof(test2)); //alerts 'undefined', surprise! 

test1(); //alerts 'function' because test2 is a function.

ECMAScript differentiates between two based on a context. If a function foo(){} is part of, say, assignment expression, it is considered a function expression. If, on the other hand, function foo(){} is contained in a function body or in a (top level of) program itself — it is parsed as a function declaration.

// declaration, since it's part of a Program
function foo(){};

// expression, since it's part of an AssignmentExpression
var bar = function foo(){};

// expression, since it's part of a NewExpression
new function bar(){};

(function(){
  function bar(){} // declaration, since it's part of a FunctionBody
})();

A somewhat less obvious example of function expression is the one where function is wrapped with parenthesis — (function foo(){}). The reason it is an expression is again due to a context: "(" and ")" constitute a grouping operator and grouping operator can only contain an expression

function foo(){} // function declaration
(function foo(){}); // function expression: due to grouping operator
  
try {
  // grouping operator can only contain expression, 
  //not a statement (which `var` is)
  (var x = 5); 
} catch(err) {
  // SyntaxError
}

Immediately-Invoked Function Expression (IIFE)

The most widely accepted way to tell the parser to expect a function expression is just to wrap in in parens, because in JavaScript, parens can’t contain statements. At this point, when the parser encounters the function keyword, it knows to parse it as a function expression and not a function declaration.

// Either of the following two patterns can be used to immediately invoke
// a function expression, thus creating an anonymous closure with privacy.

(function(){ /* code */ })(); // I've been using this one
(function(){ /* code */ }()); // Crockford recommends this one

// Because the point of the parens or coercing operators is to disambiguate
// between function expressions and function declarations, they can be
// omitted when the parser already expects an expression (but please see the
// "important note" below).


In cases where the extra “disambiguation” parens surrounding the function expression are unnecessary (because the parser already expects an expression), it’s still a good idea to use them when making an assignment, as a matter of convention. Such parens typically indicate that the function expression will be immediately invoked, and the variable will contain the result of the function, not the function itself.

Properties

arguments

A local variable that points to the "arguments" object, which contains all of the arguments passed into the function. Use "arguments.length" to determine the number of arguments entered. You can use this property to define functions that accept varying number of parameters.

caller

References the function in which the current function is called inside of. If the current function is called at the top level, caller returns null. You can use this property to check the context in which a function is being called.

function myresidence(){
 calltest()
}

// alerts function myresidence(), 
// the function in which calltest() was called inside
myresidence() 

prototype

Lets you add custom properties and methods to a function's prototype object, which instantly adds them to all instances of the function initialized using the new operator (also called a constructor function). In the below, I'm adding a getprice() method to the constructor function Car() that is reflected on all instances of new Car():

function Car(baseprice, years_old){
 this.baseprice=baseprice
 this.history=years_old
}

//add method getprice() to all instances of Car (called using new Car())
Car.prototype.getprice=function(){
 this.price=this.baseprice - (this.history * 1000)
 alert(this.price)
}

var mytoyota=new Car(20000, 10)
mytoyota.getprice() //alerts 10,000

var myford=new Car(18000, 5)
myford.getprice() //alerts 13,000

You can also use the prototype object to extend prebuilt JavaScript objects that are initialized using the new operator with custom methods, such as with Date(), Array(), or String(). Lets extend the default String object with a backwards() method that takes a string and returns it backwards (ie: "george" becomes "egroeg"):

String.prototype.backwards=function(){
 var strlen=this.length, reversestr=''
 //loop through each char within string backwards
 for (var i=strlen-1; i>-1; i--) 
  reversestr+=this.charAt(i)
 return reversestr
}

document.write('george'.backwards()) //writes out "egroeg"

Methods

funcA.apply(funcB, [argument1, argument2, argumentN])

Lets you call a function (funcA) as if it's a method of another function (funcB). Specifically, the "this" keyword when used inside funcA now returns funcB. Identical to call() below, except any arguments passed into funcA should be wrapped in an array.

funcA.call(funcB, argument1, argument2, argumentN)

Lets you call a function (funcA) as if it's a method of another function (funcB). Specifically, the "this" keyword when used inside funcA now returns funcB. The two methods apply() and call() are useful when you wish an object to "borrow" a method from another object and use it within its own context.

The following illustrates this:
function borrowme(name){
 this.bonus=(this.salary * 0.15) + (this.seniority * 500)
 alert(name + ", your bonus for this year is: " + this.bonus)
}

function employee(seniority, salary){
 this.seniority=seniority
 this.salary=salary
}

var employee1=new employee(10, 30000) 
//returns "Sarah, your bonus for this year is: 9500"
borrowme.call(employee1, "Sarah") 

Here the custom object "employee" uses the function "borrowme()" to manipulate a few numbers stored within it. Normally the keyword "this" in borrowme() references just that- the function itself. However, when it''s invoked using call(), the context of "this" changes so it references the object passed into the first parameter of call(), or in this case, "employee1".

apply() and call() are important tools in implementing inheritance in JavaScript.

toString()

Returns a string that represents the source code (raw text) of the function. A useful method in debugging, by looking at the source code of a function.

my thanks to:
http://www.javascriptkit.com/jsref/function.shtml
http://kangax.github.com/nfe/
http://benalman.com/news/2010/11/immediately-invoked-function-expression/

0 comments:

Post a Comment