A Quick Look at the JavaScript apply() Method
Tags: webdev, javascript, dom
Published: 2023-11-12 02:32:27

![JPE icon](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8c62crqemlh0x972jja2.png)

This article was originally published on [JavaScript in Plain English](https://medium.com/javascript-in-plain-english/a-quick-look-at-the-javascript-call-method-b5b2383eb4e6).

---

![Woman Computer Programmer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/otp9f8m5x30ufy2jxzr7.png)

###### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Photo by [Kelly Sikkema](https://unsplash.com/@kellysikkema?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/javascript-programmers?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)

---

## &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Table of Contents

### <a href="#intro">Introductory Remarks</a>
### <a href="#recap">A Brief Recap</a>
### <a href="#getStarted">Let's Get Started</a>
### <a href="#changeNeeded">What Needs to Change?</a>
### <a href="#refactor">Now Let's Refactor the Code</a>
#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_<a href="#neededChange">Step 1: Make the Needed Changes to index.html</a>_
#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_<a href="#renameStyle">Step 2: Rename the CSS Style Sheet</a>_
#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_<a href="#refactorDog">Step 3: Refactor the dog Objects to Use the apply() Method</a>_
#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_<a href="#howDiffer">How Does Function.prototype.apply() Differ from Function.prototype.bind()?</a>_
#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_<a href="#recommended">Recommended Reading for Study of call(), bind() and apply()</a>_
#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_<a href="#refactorButtons">Step 4: Refactor the Event Listeners for button1 through button3</a>_
### <a href="#nyext">What's Next?</a>
### <a href="#cited">Works Cited</a>

---

<a id="intro"></a>
In the third of three tutorials, we will examine the use of the `apply()` method.

Our main focus is refactoring the finished product from the previous tutorial so that it takes advantage of the `apply()` method, rather than the `bind()` method.

If you have not read the second tutorial in this series, you would do best to read through _[A Quick Look at the JavaScript bind() Method](https://dev.to/rhieger/a-quick-look-at-the-javascript-bind-method-understand-the-bind-method-in-javascript-7hh)_. Certainly, if you have not worked through the first tutorial in the series, you would do best to review _[A Quick Look at the JavaScript call() Method](https://dev.to/rhieger/a-quick-look-at-the-javascript-call-method-5ghc)_.

Our starting point will be the finished code from the second tutorial in this series.

<a id="recap"></a>
### A Brief Recap

Whereas the previous tutorial resulted in a simple demo application that demonstrated the use of the `bind()` method, in this tutorial we will refactor the same application to take advantage of the `apply()` method.

**Figure 1** below shows the starting point for this tutorial&mdash;the opening screen of the application:

<br>
![Opening Screen My Favorite Dogs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zkk3yv5is1zsqenis2xk.png)

###### <center>Fig. 1 My Favorite Dogs Opening Screen</center>

<br>
When finished, the refactored application should produce exactly the same output as its two predecessors.

<a id="getStarted"></a>
### Let's Get Started

To get started, please download the [tutorial starter code](https://github.com/RHieger/my-favorite-dogs/blob/4b7d6c7a4b71d40a42fa3bc12b0eb25ea7e0c521/starter-code-tutorial-3.zip). Simply click the download icon found in the Github link as shown below in **Figure 2**:

<br>


![Download Starter Code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikwc6w3ymcrb1nomh7d7.png)
###### <center>Fig. 2 Github Starter Code Download Page</center>

<br>
You can unzip the archive onto your local drive and you will see the following project files as shown in **Figure 3** below:

<br>
![Project Files](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/329hd1dlvd0g4ooucvxz.png)
###### <center>Fig. 3 Starter Code Project Files</center>

<br>
<a id="changeNeeded"><a/>
### What Needs to Change?

Two main parts of the application will require refactoring. The first is the **index.html** file, itself, changed mainly for semantic reasons and consistency with the refactored application's purpose. The second is the **app.js** file, and here the change is more extensive and substantive.

**Code Listing 1** below shows the first block of code that will need to be refactored:

```javascript
// Bound functions:
const dog1 = getDogInfo.info.bind(breed1);
const dog2 = getDogInfo.info.bind(breed2);
const dog3 = getDogInfo.info.bind(breed3);

// Dog Data Arrays
const dogBreed1 = dog1();
const dogBreed2 = dog2();
const dogBreed3 = dog3();
```
###### <center>Code Listing 1 Dog Objects and the dogBreed Arrays Resulting from their Invocation</center>

<br>
In **Code Listing 1**, we see three `dog` objects. The values stored in these objects are derived from the `getDogInfo` object, on which the `info()` method is called and bound to the `breed` object, which, in turn, contains the properties of each favorite dog breed.

In the code that follows, `dog1` through `dog3` are called and return three arrays assigned to `dogBreed1` through `dogBreed3`. This was the method employed in the last tutorial to assemble the data that populates the three rows of data on favorite dog breeds.

**Code Listing 2** below shows the last block of JavaScript code with which we are concerned in this tutorial:

```javascript
// Button Event Listners:
button1.addEventListener( 'click', () => {
  setRowCotent(
    breedOne,
    breedOrigin1,
    breedAvgLife1,
    dogBreed1
  );
});

button2.addEventListener( 'click', () => {
  setRowCotent(
    breedTwo,
    breedOrigin2,
    breedAvgLife2,
    dogBreed2
  );
});

button3.addEventListener( 'click', () => {
  setRowCotent(
    breedThree,
    breedOrigin3,
    breedAvgLife3,
    dogBreed3
  );
});
```

As in the second tutorial of this series, we will need to refactor the event listeners for **button1** through **button3**. **button4** remains uniform in all three tutorials in this series.

<a id="refactor"></a>
### Now Let's Refactor the Code

We can now refactor the code to take advantage of the `apply()` method. Once you have unzipped the starter code archive, follow the steps below:

<a id="neededChange"></a>
#### _Step 1: Make the Needed Changes to_ **index.html**

```html
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>bind() Method Demo</title>
  <script src="./js/app.js" defer></script>
  <link rel="stylesheet" href="./css/bind-demo.css">
</head>
```
###### <center>Code Listing 3 <head> Section of index.html</center>

As in the previous tutorial, we are concerned only with two lines in **Code Listing 3** above.

Make the following changes to **index.html:**

1) Change the line with the `<title>` tag so it reads as follows:

```html
<title>apply() Method Demo</title>
```

2) Change the line with the `<link>` tag so it reads as follows:

```html
<link rel="stylesheet" href="./css/apply-demo.css">
```

<br>
<a id="renameStyle"></a>
#### _Step 2: Rename the CSS Style Sheet_

If you refer to **Figure 3** above, you will see that the CSS style sheet is named **bind-demo.css**. This name does not match the name of the style sheet referenced in our revised `<link>` tag.

Rename **bind-demo.css** to **apply-demo.css**.

If you open **index.html** in your browser, everything will display correctly. In fact, if you click the buttons of the app, they will function exactly as they did in the previous tutorial. This is due to the original code in our starter files for the project.

> **_Now we can explore in depth how to refactor the application logic found in_ app.js _so that it takes advantage of the_ `apply` _method instead of the_ `bind()` method.**

<br>
<a id="refactorDog"></a>
#### Refactor the dog Objects to Use the `apply()` Method

```javascript
// Get info for each breed object:
const getDogInfo = {
  info: function() {
    return [
      this.breed,
      this.origin,
      this.lifeSpan
    ];
  }
};

// Bound functions:
const dog1 = getDogInfo.info.bind(breed1);
const dog2 = getDogInfo.info.bind(breed2);
const dog3 = getDogInfo.info.bind(breed3);

// Dog Data Arrays:
const dogBreed1 = dog1();
const dogBreed2 = dog2();
const dogBreed3 = dog3();
```
###### <center>Code Listing 4 The getDogInfo Object and the Derived dog Objects</center>

Let's review the code above in **Code Listing 4** to better understand what we will be changing in the refactored code.

In our starter code, the `info()` method is called on the `getDogInfo` object, and the `bind()` method is chained to the `info()` method.

Three sequentially numbered `breed` objects are passed to the `bind()` method and the results are store to three sequentially numbered `dog` objects.

Finally, as shown in the finished code from the last tutorial, each `dog` object is called and its results stored in the sequentially numbered `dogBreed` objects, the contents of which are arrays containing the dog breed information to be injected dynamically in the table rows shown above in **Figure 1** at the beginning of this article.

Our objective in refactoring the code seen in **Code Listing 4** is to replace the `bind()` method called on the `dog` objects with the `apply()` method.

<a id="howDiffer"></a>
#### _How Does_ `Function.prototype.apply()` _Differ from_ `Function.prototype.bind()`_?_

The `bind()` method returns a new function that, upon being called, has its reference to which the keyword `this` is set. It may also have a set of optional arguments that must precede any that are passed at the time the new returned function is called.

The `apply()` method, in contrast, calls a function whose reference for the `this` keyword has been set, and then an array (or array-like object) containing any arguments required in the function.

> **_Now let's see how to refactor this code in_ Code Listing 4 _above to take advantage of the_ `apply()` _method_.**

Make the following changes to the code:

In place of the `dog` object declarations above in **Code Listing 4**, type in the code listed below in **Code Listing 5**:

```javascript
// Bound functions:
const dog1 = getDogInfo.info.apply(
  breed1, [
    breed1[0],
    breed1[1],
    breed1[2]
  ]
);

const dog2 = getDogInfo.info.apply(
  breed2, [
    breed2[0],
    breed2[1],
    breed2[2]
  ]
);

const dog3 = getDogInfo.info.apply(
  breed3, [
    breed3[0],
    breed3[1],
    breed3[2]
  ]
);
```

###### <center>Code Listing 5 Refactoring of 3 dog Objects</center>

<br>
There are two notable differences in the code for the three `dog` objects above. The first is that the `bind()` method is replaced by the `apply()` method. The remaining difference in our refactored code has bigger implications, as we will soon see.

The first argument to the `apply()` method in the objects defined above is a reference object to which the `this` keyword refers. Then there is an array of arguments, as discussed above. In this case, the arguments are the elements of the array that contains the content to go into the three table cells of each row containing dog breed information.

The second rather notable difference is that when using the `apply()` method, because no new object is returned, as is the case when using `bind()`, there is no longer any need to create `dogBreed` objects to model the data for the table rows, as shown earlier in **Code Listing 4**.

This definitely makes for more compact code, cutting out a full three lines of code. As we directly access the values stored in the `dog` objects created with the `getDogInfo.info()` method call, also shown above in **Code Listing 5**, we are able to access the indices in the `dog` arrays directly, eliminating an interim step.

**Does this mean that the** `bind()` **method is inefficient or undesirable?** In this case, the answer is bigger than the question. The concepts involved are fairly advanced, but several articles have been published that explore the question of optimum use cases for the three methods&mdash;`call()`, `bind()` and `apply()`&mdash;explored in this tutorial series.

<a id="recommended"></a>
#### _Recommended Reading for Study of_ `call()`, `bind()` _and_ `apply()`

<p>&nbsp;</p>

> **_One fairly comprehensive article that is worth a read is_** _<a href="https://www.eigenx.com/blog/https/mediumcom/eigen-x/how-and-when-to-use-bind-call-and-apply-in-javascript-77b6f42898fb" target="_blank">How AND When to use bind, call, and apply in JavaScript</a>. **This article gives a broad overview of the relative utility and good use cases for each method. Though the information in this article is definitely fairly advanced, it is worthwhile to spend some time with the ideas expressed there as they begin to clarify how best to use each of these methods.**_

 <br>
<a id="refactorButtons"></a>
#### _Step 4: Refactor the Event Listeners for_ button1 _through_ button3

As one final step in our refactoring, one subtle change must be made to the event listeners for `button1` through `button3`, as shown earlier in **Code Listing 2**.

Referring back to **Code Listing 2**, you will note that the last argument in the `setRowContent()` callback function reads `dogBreed1`, `dogBreed2` and `dogBreed3`. These arguments hearken back to our previous iteration of the application, which used the `bind()` method.

The `bind()` method, as you will recall, set the value of the `this` keyword to the specified object&mdash;in our case `breed1`, `breed2` and `breed3`. However, in the process, a new object is returned. In order to access the properties in that object the `info()` method was called and the `apply()` method was chained to it. The result was stored in brand new arrays stored to the constants `dogBreed1`-`dogBreed3`.

Using the `apply()` method, we can cut out this "middleman" step, by allowing access directly to the properties within the object reference set for the `this` keyword. We may therefore access properties from `dog1`, `dog2` and `dog3`.

For convenience, **Code Listing 6** below shows the relevant code to be refactored:

<br>
```javascript
// Button Event Listeners:
button1.addEventListener('click', () => {
  showRowContent(
    breedOne,
    breedOrigin1,
    breedAvgLife1,
    dogBreed1
  );
});

button2.addEventListener('click', () => {
  showRowContent(
    breedTwo,
    breedOrigin2,
    breedAvgLife2,
    dogBreed2
  );
});

button3.addEventListener('click', () => {
  showRowContent(
    breedThree,
    breedOrigin3,
    breedAvgLife3,
    dogBreed3
 );
});
```

###### <center>Code Listing 6 Event Listeners to be Refactored</center>

<br>
Refactoring the above code is fairly trivial&mdash;merely a change of the last argument in each of the `setRowContent()` methods. But as discussed earlier, the implications of this change are significant because the extra step of saving the values to be placed in each row to constants is eliminated.

Now we do the refactoring of the code above, making the minor changes described above. Make sure that your code matches that shown in **Code Listing 7:**

<br>
```javascript
// Button Event Listeners:
button1.addEventListener('click', () => {
  showRowContent(
    breedOne,
    breedOrigin1,
    breedAvgLife1,
    dog1
  );
});

button2.addEventListener('click', () => {
  showRowContent(
    breedTwo,
    breedOrigin2,
    breedAvgLife2,
    dog2
  );
});

button3.addEventListener('click', () => {
  showRowContent(
    breedThree,
    breedOrigin3,
    breedAvgLife3,
    dog3
  );
});
```
###### <center>Code Listing 7 Refactored Event Listeners for button1 through button3</center>

<br>
Now that these changes have been implemented, you can see the results by pointing your browser at the **index.html** file in your application folder, or by going to the page live on [codepen.io](https://codepen.io/RHieger/full/mdmLLyL).

<a id="nyext"></a>
### What's Next?

At the end of the first tutorial, I mentioned that the little application we created is simplistic and does not take into account user input. As a result, there is the rather artless paradigm of a button bar with four buttons, three of which fill in details about three pre-determined dog breeds and one that resets the table to its initial state. I indicated that I would be refactoring the current application to be a far more robust, dynamic and user interactive Single Page Application (SPA).

The current application barely qualifies as an application with dynamic generation of data. I intend to build a new version soon, which will include a modal dialogue in which a user can input the dog breed information of choice. The breeds will therefore not be pre-determined as in this version of the application.

The implications of these changes are profound from a user interface perspective and also a data validation perspective, as it cannot be predicted ahead of time what a user will enter, and whether the data entered is valid.

Please stay tuned for my next tutorial&mdash;_My Favorite Dogs&mdash;A Simple Single Page Application (SPA)._

---

<a id="cited"></a>
## <center>Works Citied</center>

Hieger, Robert. "A Quick Look at the bind() Method:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Understand the bind() Method in JavaScript." _dev.to,_<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEV Community, 22 Aug 2021, [https://dev.to/rhieger/a-quick-look-at-the-javascript-bind-method-understand-the-bind-method-in-javascript-7hh](https://dev.to/rhieger/a-quick-look-at-the-javascript-bind-method-understand-the-bind-method-in-javascript-7hh)

---. "A Quick Look at the JavaScript call() Method." _dev.to,_<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEV Community, 5 May 2021, [https://dev.to/rhieger/a-quick-look-at-the-javascript-call-method-5ghc](https://dev.to/rhieger/a-quick-look-at-the-javascript-call-method-5ghc).

"How and When to Use bind, call, and apply in JavaScript."<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_Eigenx,_ Eigen X, 2 Aug. 2018 [https://www.eigenx.com/blog/https/mediumcom/eigen-x/how-and-when-to-use-bind-call-and-apply-in-javascript-77b6f42898fb](https://www.eigenx.com/blog/https/mediumcom/eigen-x/how-and-when-to-use-bind-call-and-apply-in-javascript-77b6f42898fb).