Call, Apply and Bind in JavaScript
Tags: javascript, webdev, programming
Published: 2022-03-09 13:04:10

Given the various ways in which the infamous `this` keyword can be altered in JavaScript (global, functions, arrow functions, classes, objects, etc.) it’s not surprising that somewhere along the way functionality started appearing that helps alter the calling context, and thus the value of `this` . Three particular functions that have appeared to help are **Call**, **Apply** and **Bind**, and there’s a reason that I list them in that order.

## Call

Think of **Call** as being like saying “I’d like to call something, but I’d like to provide my own context for where it gets called”. This makes a lot of sense when you look at objects and classes. Take the following example:

{% embed https://gist.github.com/DuncanMcArdle/9484aa385e634ae42faf4d18710f89f3 %}

What we’re doing here is that we’re taking the `toyotaHilux` object, which has no `beepHorn()` method, and using it as the context for a call to the `fordFocus` object’s `beepHorn()` method. It’s kind of like saying, “Hey `fordFocus`, pretend you’re `toyotaHilux` for a second, and then call that great `beepHorn()` method of yours”.

In addition to the context we provide to **Call**, we can also provide some parameters to be passed to the target method, like so:

{% embed https://gist.github.com/DuncanMcArdle/5ca4a4267befc550176710274430b34a %}

## Apply

Think of **Apply** as being like **Call**, but with the ability to supply parameters to the target function as an array rather than standard parameters. Otherwise, it’s more or less identical:

{% embed https://gist.github.com/DuncanMcArdle/f24afc7191a9fb2e9b373fd11aff70b1 %}

Now you may be wondering why the parameters are supplied as an array. The reason for this is that as **Apply** could be called on a function with no parameters, 2 parameters or even 427 parameters, it makes it much more manageable to pass it an array of parameters instead.

Interestingly, this additional functionality over **Call** also provides us with another feature: the ability to call functions with an array of parameters. Here’s an example:

{% embed https://gist.github.com/DuncanMcArdle/08b874c57fdfe2c70fb81218f6781fb0 %}

As you can see we have a simple addition function which takes 2 parameters. The way we’re calling it however is to use **Apply**, supplying no context (as there’s no use of `this`), and then providing an array of parameters to be passed. **Apply** then handles converting this array into traditional parameters, and calls the function. I’ve also included an attempt to call the function with the array without using **Apply** to demonstrate what happens normally.

Now just for completeness sake, you might be wondering how this technique performs if the array of parameters provided is bigger or smaller than the parameters the function is expecting. Well the answer is that if you don’t provide enough parameters, the missing ones will be become `undefined` (unless you declare a default value in the function declaration), and if you provide too many it’ll just chop off the excess. Here’s an example:

{% embed https://gist.github.com/DuncanMcArdle/e7cbbd7ce98a33bdf5caa0d3f8ae2109 %}

Now this isn’t necessarily the best way to convert an array to parameters, but it’s a common one you’ll see on coding challengers, and it’s an interesting case of taking something that’s been designed for one purpose, and using it for something completely different.

## Bind

Think of Bind as being like a re-usable version of **Call**. You declare a variable, and then bind it to the target function, with an optional target context, and provide some optional parameters, and then you can call it whenever you want.

Let’s first look at an example of binding with a context provided:

{% embed https://gist.github.com/DuncanMcArdle/e76d3d7530fc040b5394f8b8750c33f9 %}

As you can see, it’s basically the same as a **Call**, but re-usable.

Now let’s look at an example of **Bind** that supplies some parameters:

{% embed https://gist.github.com/DuncanMcArdle/834962735d803d039aa5bcb5f6219b89 %}

Finally let’s bring everything together by binding to a function and supplying both context and parameters:

{% embed https://gist.github.com/DuncanMcArdle/d6f3dd3b6d375e447390e31c619bb920 %}

As you can see, the `boundInflateToyotaTyre` variable is bound to calling the `inflateTyre` method of the `fordFocus` object, but using the `toyotaHilux` context.

**Note:** I’d be remiss if I didn’t point out that the more helpful use-case for **Bind** in this example would be to bind _without_ the parameters, so they can be specified at call time, such as in the following example:

{% embed https://gist.github.com/DuncanMcArdle/7cd8a36ef3c3bef80a8d9334d92e64e1 %}