Buy @ Amazon

Search This Blog

February 6, 2014

Understanding call and apply in Javascript by example

In Javascript, call(..) and apply(..) does the same thing, just that the way each takes input feed is different. All Javascript Function objects have these methods at their disposal.


The Syntax


call(..) has the following syntax
func.call(thisArg,[arg1, arg2, .., argN]);
where,
thisArg is the value of this provided for the call to func
arg1, arg2,.., argN are column of arguments to the function func


apply() has the following syntax
func.apply(thisArg, [argsArray]);
where,
thisArg is the value of this provided for the call to func
argsArray is an array or an array-like object that has a property length and integer properties in the range of [0..length]. Example of such array-lke object could be {'length': 3, '0':'javascript', '1':'is', '2':'fun'}

Learning by example


So where does all this lead to? We are going to use call(..) or apply(..) depending on the context.

Let's take for instance we don't want to use console.log(..) every time we want to log something to the console. We are one helluva lazy developers, and so wanted to define a log(..) function that in turn delegates the work to console.log(..) for the actual work.

Lets start writing the desired log function in different ways to figure out the right pick:
function log1() { console.log(arguments); }

function log2() { console.log.apply(console, arguments); }

function log3() { console.log.call(console, arguments); }

Can you figure out the problem?

Lets try the following code for output and check for the difference:
console.log("asd"); //outputs: asd
log1("asd"); //outputs: ["asd"]
log2("asd"); //outputs: asd
log3("asd"); //outputs: ["asd"]

We see that log2(..) is our desired function definition. Let's give a couple of more attempts on the log2(..) to see if it mimics console.log(..) without any surprise:
console.log("asd","dfg"); //outputs: asd dfg
log2("asd","dfg"); //outputs: asd dfg

console.log(["asd","dfg"]); //outputs: ["asd", "dfg"]
log2(["asd","dfg"]); //outputs: ["asd", "dfg"]

Yay, log2(..) is the winner! Or put rightly, apply(..) is the winner in this context.

So the next time round, you are confused between call(..) and apply(..) don't worry too much. Just give each a try and see which fits the puzzle.