Javascript call and apply 101

December 1, 2019

If you spent enough time reading Javascript codes, you probably saw call and apply. If you are like me, you get confused real fast. Don't worry, these methods are pretty easy to understand. I will cover some of the basics to get you all started!

I will go over:

  1. How to use call
  2. How to use apply
  3. When to use call and when to use apply

Before we start, keep in mind that these two are very similar. Learning one allows us to understand the other.

Using call

Suppose we have an object and a function:

const breakfastObj = {
  food: 'blueberry waffles',
  drink: 'orange juice'
}

function sayBreakfast(){
  console.log(`I had ${this.food} and ${this.drink} for breakfast`)
}

When we call sayBreakfast(), it will return

sayBreakfast() // I had undefined and undefined for breakfast

To "call" the function sayBreakfast() with breakfastObj as this:

sayBreakfast.call(breakfastObj) // I had blueberry waffles and orange juice for breakfast

Recall that this, if not defined, refers to global object (if you are on browser, your global object is probably window object). So we can do this:

window.food = 'French toast'
window.drink = 'Apple juice'
sayBreakfast() // ... French toast and Apple juice

This is equivalent to:

sayBreakfast.call() // ... French toast and Apple juice

Call also accepts 2nd, 3rd, ...nth arguments. These arguments are used as function's arguments. Let's look at example to clarify:

const lunchObj = {
  food: 'tacos',
  drink: 'water'
}

function sayLunch(location){
  console.log(`I had ${this.food} and ${this.drink} for lunch at ${location}`)
}

sayLunch.call(lunchObj, "Taco Bell") // I had tacos and water for lunch at Taco Bell

Hmm, tacos sound good 🤤. If the function accepts multiple arguments, we can pass them too:

function sayLunch(location, company, time){
  console.log(`I had ${this.food} and ${this.drink} for lunch at ${location} with ${company} in the ${time}`)
}

sayLunch.call(lunchObj, "Taco Bell", "Jon and Juan", "afternoon") // I had tacos and water for lunch at Taco Bell with Jon and Juan in the afternoon

Using apply

apply works like call. The only difference is the way they accept function arguments. apply uses array instead of separated by comma: myFunction.apply(obj, [arg1, arg2, argn])

Using our example earlier, but with apply:

const lunchObj = {
  food: 'tacos',
  drink: 'water'
}

function sayLunch(location, company, time){
  console.log(`I had ${this.food} and ${this.drink} for lunch at ${location} with ${company} in the ${time}`)
}

sayLunch.apply(lunchObj, ["Taco Bell", "Jon and Juan", "afternoon"])

We can take advantage of apply's array arguments with ES6's spread operator

Here is a shameless copy-paste from mozilla page:

function sum(x, y, z) {
  return x + y + z;
}

const numbers = [1, 2, 3];

console.log(sum(...numbers));
// expected output: 6

console.log(sum.apply(null, numbers));
// expected output: 6

Keep in mind we can use call and/or apply into built-in functions, not custom functions. Something like this:

const someArr = ["foo", "bar", "baz"];

console.log.apply(null, someArr) // foo bar baz

And if we want to get fancy and append a new argument into someArr:

console.log.apply(null, ['hello', ...someArr]) // hello foo bar baz

How to remember call vs apply arguments

A trick to remember which one is which is to look at their first letter (credit SO)

  • A -> Apply -> Array
  • C -> Comma -> Call

We only scratched the surface, but hopefully this should be enough to apply (pun intended 😎) your knowledge for more advanced stuff!

Resources/ more readings: