JavaScript’s Call and Apply

A simple heuristic for remembering how to use call and apply

JavaScript’s Call and Apply
Code in text editor

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.

  1. Your functions shouldn’t be taking so many arguments that using call becomes an eyesore.
  2. 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);