Quick Guide to Call, Apply, Bind in JavaScript

Annie Liao - Jul 18 '20 - - Dev Community

Back in February, I created a quiz to help myself and others better understand the this keyword in JavaScript. At the time, I didn't delve into ways to explicitly determine what object this is referring to, i.e. using call, apply, and bind methods.

Fast forward to this week, I came across the call method when exploring the zooming effect of d3.js (a data visualization library):

svg.call(d3.zoom().on('zoom', () => {
  g.attr('transform', d3.event.transform)
}))
Enter fullscreen mode Exit fullscreen mode

As with any tools, it is easy to forget how to use them if you don't encounter them frequently. So here's a quick reference to all three methods as a reminder of their usage and differences.

Call() and Apply()

How They are Similar

Both call and apply methods allow us to specify what the this keyword should reference, and invoke the function immediately.

For instance:

function covidAlert() {
  alert(`To stop the spread, please ${this.outdoor}.`)
}

const measures = {
  indoor: 'wash your hands',
  outdoor: 'wear a mask',
  social: 'keep 6-feet distance'
}
Enter fullscreen mode Exit fullscreen mode

We cannot use measures.covidAlert() because measures object doesn't have covideAlert function as its execution context.

This is where the call or apply method comes to our rescue:

covidAlert.call(measures)
// or:
covidAlert.apply(measures)

// => To stop the spread, please wear a mask.
Enter fullscreen mode Exit fullscreen mode

How They are Different

If you want to pass arguments to the function, you can do so by passing in the arguments one by one using the call method.

function covidAlert(phaseNum, date, state) {
  alert(`To stop the spread, please ${this.outdoor}, so we can enter phase ${phaseNum} on ${date}. We are #${state}Smart.`)
}

const measures = {
  indoor: 'wash your hands',
  outdoor: 'wear a mask',
  social: 'keep 6-feet distance'
}

covidAlert.call(measures, 'four', 'July 20th', 'NewYork')
// => To stop the spread, please wear a mask, so we can enter phase four on July 20th. We are #NewYorkSmart.
Enter fullscreen mode Exit fullscreen mode

With apply, you should pass in an array of arguments, like so:

function covidAlert(phaseNum, date, state) {
  alert(`To stop the spread, please ${this.outdoor}, so we can enter phase ${phaseNum} on ${date}. We are #${state}Smart.`)
}

const measures = {
  indoor: 'wash your hands',
  outdoor: 'wear a mask',
  social: 'keep 6-feet distance'
}

const reopenDetails = ['four', 'July 20th', 'NewYork']

covidAlert.apply(measures, reopenDetails)
// => To stop the spread, please wear a mask, so we can enter phase four on July 20th. We are #NewYorkSmart.
Enter fullscreen mode Exit fullscreen mode

Bind()

The bind method is useful when you do NOT want to invoke the function immediately. Instead, bind creates a copy of the function that you can invoke later.

You can also pass in arguments with the bind method one by one, just like how you do it with call:

function covidAlert(phaseNum, date, state) {
  alert(`To stop the spread, please ${this.outdoor}, so we can enter phase ${phaseNum} on ${date}. We are #${state}Smart.`)
}

const measures = {
  indoor: 'wash your hands',
  outdoor: 'wear a mask',
  social: 'keep 6-feet distance'
}

const functionToBind = covidAlert.bind(measures, 'four', 'July 20th', 'NewYork')

functionToBind()
// => To stop the spread, please wear a mask, so we can enter phase four on July 20th. We are #NewYorkSmart.
Enter fullscreen mode Exit fullscreen mode

And that's a wrap! To learn more about the specifics of this keyword and its execution context in JavaScript, I recommend reading the following two articles. Their clear explanations and practical use cases really solidified my understanding of function binding:

. . . . . . . . . . . . . . . . . . . . . . . . . . .