Javascript Bind, Apply and Call Concepts
Published: 2022-11-18 19:05:15

## BIND 

- **Introduction**

The bind() method creates a new function that, when called, has its this keyword set to the provided value . 

The syntax is given as : 

```javascript
bind(thisArg)
bind(thisArg, arg1)
bind(thisArg, arg1, arg2)
bind(thisArg, arg1, arg2, /* …, */ argN)
```
In this syntax, the bind() method returns a copy of the function fn with the specific this value (thisArg) and arguments (arg1, arg2, …). 

Unlike the call() and apply() methods, the bind() method doesn’t immediately execute the function. It just returns a new version of the function whose this sets to thisArg argument.

thisArg ⇒ The value to be passed as the this parameter to the target function func when the bound function is called.

arg1, …, argN ⇒ Arguments to prepend to arguments provided to the bound function when invoking func.

- **Use Bind for function binding**

When you pass a method of an object to another function as a callback, the this is lost. For example:

```javascript
let person = {
  name: "John Doe",
  getName: function () {
    console.log(this.name);
  }
};


function someFunc(obj){
obj();

}

someFunc(person.getName); 
```

This will result in 

![passing as a callback error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/adymdftxk7o3oixe73nb.PNG)

As you can see clearly from the output, the person.getName() returns undefined instead of 'John Doe'.

_this is because_ :

When a callback is executed within a higher-order function, it gets assigned a this property that is completely dependent on how it is invoked and not where/how/when it was defined.

In the example above, we have a function called someFunc(higher-order function), and it takes in a callback function that logs this.name value to the console but it now points to the global object because it is invoked in a global scope . 

_This issue can be resolved with bind :_

```javascript
let person = {
  name: "John Doe",
  getName: function () {
    console.log(this.name);
  }
};
let f = person.getName.bind(person);


function someFunc(obj){
obj();

}

someFunc(f); 
```
This will result in correct output : 


![Bind_successful output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mvivfx1mul4ao41eqxso.png)


## APPLY 

The apply() method calls the specified function with a given this value, and arguments provided as an array (or an array-like object).

- **Syntax**

```javascript
apply(thisArg)
apply(thisArg, argsArray)
```
thisArg is the value you give when you call the function . 

argsArray (optional) an array-like object, specifying the arguments

- **Use of Apply**

You can add an element to an array by using Array.prototype.push(). You can push a number of elements at once because push() accepts a variable number of arguments. However, if you supply an array to push(), it will actually add the entire array as a single element rather than each element separately, creating an array inside of an array.

```javascript
const array = ["a", "b"];

array.push([0,1,2]);

console.log(array)
```
This will give the output as 


![Array push with array as a param](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19y320xix5kpdngkn21b.png)

Apply can be used in this situation to implicitly "spread" an array as a set of arguments.

```javascript
const array = ["a", "b"];
const elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]
```

This will result in : 


![Apply method result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n16kk9g9q50knzc2lcgo.png)

This is because the argsArray parameter of apply method is an array-like object and it supplies each element in the elements array individually . 

- **Another example is :**

```javascript
const numbers = [5, 6, 2, 3, 7];

let max = Math.max.apply(null, numbers);

// This about equal to Math.max(numbers[0], …)
// or Math.max(5, 6, …)

```
This will result in 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jj7tn17s1vw1ftuyeicl.png)

## CALL 

- **Introduction**

The call() method calls the function with a given this value and arguments provided individually.

- **Syntax**

```javascript
call()
call(thisArg)
call(thisArg, arg1, /* …, */ argN)
```
The call method initialises the this inside the function and launches it right away.

In contrast to bind(), which produces a copy of the function and sets the this keyword, call() sets the this keyword, executes the function instantly, and does not create a new copy of the function.

```javascript
function student() {
  console.log(`Hi, I am ${this.name} and I am ${this.subject} student`);
}
const asad = {
  name: 'Asad',
  subject: "Data Science",
};
const jane = {
  name: 'Jane',
  subject: "Computer Engineering",
};
// Hi, I am Asad and I am Data Science student
student.call(asad);
// Hi, I am Jane and I am Computer Engineering student
student.call(jane);
```

call() expects all parameters to be passed in individually, whereas apply() expects an array of all of our parameters.

- **Use Case of Call**


It can be used to emulate inheritance in OOP.

_Example_

```javascript
var Robert = {
    name: "Robert Rocha",
    age: 12,
    height: "5,1",
    sex: "male",
    describe: function() {
        return "This is me " + this.name + " " + this.age + " " + this.height + " " + this.sex;
    }
};
```
Lets say that the above is a master object(prototype) and you want to inherit the function describe in another object:

```javascript
var Richard = {
    name: "Richard Sash",
    age: 25,
    height: "6,4",
    sex: "male",
}
```

The Richard object does not have the describe function and you want to simply inherit ,so to speak, the function. You would do it like so:

```javascript
console.log( Robert.describe.call( Richard ) );
```
Output:
```
This is me Richard Sash 25 6,4 male
```