- A useful mnemonic for Call() and Apply() is:
- a in apply() stands for
array of arguments.
- c in call() stands for
comma separated arguments.
- a in apply() stands for
- The difference between apply() and call() is just the way arguments are passed:
- apply() : Invoke a function with arguments passed as an array.
function.apply(thisObj, arrayOfArguments);
- call() : Invoke a function with arguments passed as comma-separated.
function.call(thisObj, arg1, arg2, ...);
- apply() : Invoke a function with arguments passed as an array.
- Now let’s take a look at the ways to use them: (Below is the code snippet we will use for understanding)
var person1 = {name: 'person1', age: 20, gender: 'Male'}; var person2 = {name: 'person2', age: 19, gender: 'Female'}; var greetHi = function() { alert('Hi, ' + this.name); }; var greetBye = function() { alert('Bye, ' + this.name); };
Here, calling just
greetHi();
orgreetBye();
will give errors or unexpected results because both methods rely on their context forthis.name
, and calling these methods without explicit scope will just run them within the scope of their current window.So to run them in the scope of an Object, we need to call these methods like below and that’s how call() and apply() method are used.
// Using call() greetHi.call(person1); greetBye.call(person2); // Using apply() greetHi.apply(person1); greetBye.apply(person2);
Both the above way of calling the method using call() and apply() do the exact same thing and they get executed in the context, or scope, of the first argument passed which is an Object.
- Now we will see how to use these with arguments passed and this is where we will know when to use call() and apply():
Lets combine greetHi() and greetBye() to a single method as just greet() where we will pass ‘Hi’, ‘Bye’ as an argument.
and also create another method where it will need multiple parameters to be passed.// greetHi() and greetBye() combined to greet(). var greet = function(greet) { alert(greet + ', ' + this.name); }; // New method with multiple arguments. var setPersonInfo = function(name, age, gender) { this.name = name; this.age = age; this.size = size; }; // Call greet method using call() with single argument passed. greet.call(person1, 'Hi'); greet.call(person2, 'Bye'); //Now to call 'getPersonInfo' method using call(), we will have to pass all arguments as a comma separated like: setPersonInfo.call(person1, 'John', 25, 'Male');
This is a no big deal but limitation of call() will become apparent when you do not know the number of arguments to pass to a method like a dispatcher which will just dispatch your arguments/message to intended methods as below:
var dispatch = function(person, method, args) { method.apply(person, args); }; dispatch(person1, greet, ['Hi']); dispatch(person2, setPersonInfo, ['John', 25, 'Male']);
So here you can see that we are passing an array of arguments which are different in both of the above call of dispatch() method and then apply() is called on the method with the argument passed whose length varies in each of the methods.
That’s the difference between call and apply. Both can be called on functions, which they run in the context of the first argument.
So If you know number of arguments to pass, you should use call() and If you don’t know, or arguments are already in an array, should use apply().
I hope it gives you some clarity on call() and apply().
References:
- https://stackoverflow.com/questions/1986896/what-is-the-difference-between-call-and-apply
- http://hangar.runway7.net/javascript/difference-call-apply
- http://lucybain.com/blog/2014/call-vs-apply/
Happy coding!!