An Explanation of Bind, Call, and Apply (Javascript)
Published: 2023-12-08 19:27:45

**Introduction**
The "bind", "call", and "apply" keywords are all functions that alter the context of the "this" keyword of a function in order to allow said function to reference new data using the "this" keyword. The "this" keyword is a reference that simply points to the object that contains that instance of the "this" keyword within its scope. These three keywords allow you to change what the "this" keyword points to within a function, which can be useful for inserting data from different objects for use in functions not located within said objects. Now let's focus more on the "bind" keyword.

**Bind**
The "bind" function can create a duplicate of an existing function and force all instances of "this" within the new function to point to a new object. The syntax of a "bind" function goes as follows:

```
const nameOfNewFunction = nameOfFunction.bind(objToReference, optionalArguments...);
```

A new function name is created and assigned to the copy of another function created from the "bind" function. The name of the function that you want to copy is followed by a calling of ".bind". The first argument of ".bind" is the name of the object that you wish to redirect the "this" keyword towards. Any arguments put after the first one are pieces of data that are put into and used within the new copy of the function whenever it is called, making these arguments act like regular arguments in a regular function call. These new arguments are permanently inserted into the function based on what parameter the argument was inserted into, making it no longer possible to change the values associated with that parameter. An example of the "bind" function in use goes as follows:

```
var mathBox1 = {
  num1: 5,
  add(num2, num3) {
    let answer = this.num1 + num2 + num3;
    console.log(answer);
  }
};

var mathBox2 = {
  num1: 9,
  add(num2, num3) {
    let answer = this.num1 + num2 + num3;
    console.log(answer);
  }
};

mathBox1.add(3, 4);// result: 12 (reference)

var equation1 = mathBox1.add;
equation1(3, 4); // result:NaN...'this' is not manually set to anything, 'this' refers to the global object here. (reference)

var equation2 = mathBox1.add.bind(mathBox2);
equation2(3, 4); // result: 16

var equation3 = mathBox1.add.bind(mathBox2, 7);
equation3(4); // result: 20
```

There are two objects that each contain a number variable and an "add" function that uses "this" to add said number variable to two other numbers inputted into the function. The first function call (mathBox1.add(3, 4)) runs the "add" function in mathBox1 normally. The second function call tries to assign a variable to mathBox1.add without setting the "this" object, resulting in NaN. The third function call uses bind to make a copy of the function with the "this" pointing to the number 9 in mathBox2, resulting in the result changing from 12 to 16. The fourth function call uses bind to make a copy of the function with the "this" pointing to the number 9 in mathBox2 and forces num2 to be 7 in the function, resulting in the result changing from 16 to 20. Next up is the "call" function.

**Call**
The "call" function is very similar to the "bind" function, but it calls your desired function instead of making a copy of the function that you wish to call. Instead of making an altered copy of the function that you can call later on, the "call" function simply calls that function with the object you wish to set "this" to and the arguments you wish to pass on into the function. Here is the "call" function syntax:

```
nameOfFunction.call(objToReference, optionalArguments...);
```

The name of the function that you want to call is followed by a calling of ".call". The first argument of ".call" is the name of the object that you wish to temporarily redirect the function's "this" keyword towards for the function call. Any arguments put after the first one act like regular arguments in a regular function call and are passed into the function. An example of the "call" function in use goes as follows:

```
var mathBox1 = {
  num1: 5,
  add(num2, num3) {
    let answer = this.num1 + num2 + num3;
    console.log(answer);
  }
};

var mathBox2 = {
  num1: 9,
  add(num2, num3) {
    let answer = this.num1 + num2 + num3;
    console.log(answer);
  }
};

mathBox1.add(3, 4);// result: 12 (reference)

mathBox1.add.call(mathBox2, 3, 4); // result: 16

mathBox1.add.call(mathBox2, 7, 4); // result: 20
```
There are two objects that each contain a number variable and an "add" function that uses "this" to add said number variable to two other numbers inputted into the function. The first function call (mathBox1.add(3, 4)) runs the "add" function in mathBox1 normally. The second function call uses .call to call the function with the "this" pointing to the number 9 in mathBox2, resulting in the result changing from 12 to 16. The third function call uses .call to call the function with the "this" pointing to the number 9 in mathBox2 and inputs 7 as num2 instead of 3, resulting in the result changing from 16 to 20. Next up is the "apply" function.

**Apply**
The "apply" function is almost the same as the "call" function, but the "apply" function call now accepts an array of the arguments that you wish to insert into the function you wish to use. Here is some syntax:

```
nameOfFunction.apply(objToReference, [optionalArgumentArray]);
```

The name of the function that you want to call is followed by a calling of ".apply". The first argument of ".apply" is the name of the object that you wish to temporarily redirect the function's "this" keyword towards for the function call. Any arguments put after the first one has to be put into a single array, but otherwise act like regular arguments in a regular function call and are passed into the function. I wasn't kidding when I said that the "apply" function was almost the same as the "call" function. The only difference between this syntax and the syntax of the "call" function is that you put the arguments you wish to insert into the desired function inside of an array instead of just listing them out after the first argument like in the "call" function call. Now let's look at an example:

```
var mathBox1 = {
  num1: 5,
  add(num2, num3) {
    let answer = this.num1 + num2 + num3;
    console.log(answer);
  }
};

var mathBox2 = {
  num1: 9,
  add(num2, num3) {
    let answer = this.num1 + num2 + num3;
    console.log(answer);
  }
};

mathBox1.add(3, 4);// result: 12 (reference)

mathBox1.add.apply(mathBox2, [3, 4]); // result: 16

mathBox1.add.apply(mathBox2, [7, 4]); // result: 20
```
There are two objects that each contain a number variable and an "add" function that uses "this" to add said number variable to two other numbers inputted into the function. The first function call (mathBox1.add(3, 4)) runs the "add" function in mathBox1 normally. The second function call uses .apply to call the function with the "this" pointing to the number 9 in mathBox2 and inserts the two inputs of 3 and 4 as an array, resulting in the result changing from 12 to 16. The third function call uses .apply to call the function with the "this" pointing to the number 9 in mathBox2 and inserts the two inputs of 7 and 4 as an array, resulting in the result changing from 16 to 20. Now on to the conclusion.

**Conclusion**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ka3o435a0sc3e1q4i00u.jpg)
The three methods/functions of ".bind", ".call", and ".apply" are all tools used to reassign the "this" value/object within a function to point at the "this" value in an object to retrieve data from said object for use in the function. These are useful when you want to use data from several different objects in the same function, which can help with reducing code.

**Links to Sources Used**
-https://www.geeksforgeeks.org/explain-call-apply-and-bind-methods-in-javascript/
-https://www.freecodecamp.org/news/understand-call-apply-and-bind-in-javascript-with-examples/
-https://www.w3schools.com/js/js_this.asp
-https://stackoverflow.com/questions/2236747/what-is-the-use-of-the-javascript-bind-method