JavaScript’s Call and Apply
A simple heuristic for remembering how to use call and apply
A simple heuristic for remembering how to use call and apply
JavaScript offers us three ways of changing the meaning of this
when we invoke functions. These include:
This article assumes you understand what this
is, how to infer its meaning, and when to use each of the methods listed above. We will be focusing on the last two methods, call and apply.
What’s the difference between call and apply?
The call
and apply
methods both accomplish the same goal. They call a function with a this
value and the function’s arguments. However, they differ in how they are invoked.
The call
method takes the function’s arguments individually while the apply
method takes the function’s arguments as an array.
Here’s some code showing the difference in how call
and apply
are invoked.
function fn(arg1, arg2) {
console.log(this, arg1, arg2);
}
// arguments are comma separated
fn.call(this, arg1, arg2);
// arguments are passed as an array
fn.apply(this, [arg1, arg2]);
Remember, forever!
I spend my days in JavaScript land, so I went searching for a way to remember how to use these methods without having to check the Mozilla Developer Network every other week.
Here’s the single most useful heuristic I found on Stackoverflow, provided by the user flatline.
“A for array and C for comma.”
Or, pick one and only one
Great! Now you know how to invoke these two methods correctly without looking up their documentation, but something’s still amiss.
Why are we using both of these methods if they accomplish the same goal. We should be able to pick one and only use that one throughout our code base.
If you take a look at the ECMAScript Specification for these two methods, you’ll see more steps are taken when apply
is invoked. This is already a hint that call
might perform better, but don’t stop there. Test it!
Here’s a jsperf comparing the the performance of the two methods.
Spoiler: apply
is slower, and since they both do the same thing, just pick call
.
What about code style? That’s for you and/or your team to talk about. But, here’s my take.
- Your functions shouldn’t be taking so many arguments that using
call
becomes an eyesore. - You can set up your arguments as an array and use ES6 destructuring to make using
call
look great.
// 1. use a small number of arguments
fn.call(this, arg1, arg2);
// 2. use es6 destructuring
fn.call(this, ...args);