Quick Guide to Call, Apply, Bind in JavaScript
Tags: javascript, codenewbie
Published: 2020-07-18 18:18:43

Back in February, I created [a quiz](https://dev.to/liaowow/take-this-quiz-understand-how-this-works-in-javascript-44dj) 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):
```js
svg.call(d3.zoom().on('zoom', () => {
  g.attr('transform', d3.event.transform)
}))
```

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:
```js
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'
}
```

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:
```js
covidAlert.call(measures)
// or:
covidAlert.apply(measures)

// => To stop the spread, please wear a mask.
```

### 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. 

```js
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.
```

With `apply`, you should pass in an **array** of arguments, like so:
```js
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.
```

## 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`:
```js
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.
```

<hr>

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:
- [Understanding This, Bind, Call, and Apply in JavaScript](https://www.taniarascia.com/this-bind-call-apply-javascript/) by Tania Rascia
- [Understanding Call, Bind and Apply Methods in JavaScript](https://blog.bitsrc.io/understanding-call-bind-and-apply-methods-in-javascript-33dbf3217be) by Sukhjinder Arora