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.
call(..) has the following syntax
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
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'}
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:
Can you figure out the problem?
Lets try the following code for output and check for the difference:
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:
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.
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); }
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"]
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"]
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.