# call(), apply() and bind() methods in JavaScript

Hello readers, call, apply and bind methods are the most asked topic in JavaScript interviews as they are popularly used. Before directly heading towards the understanding of call, apply and bind methods, it is important to understand the "this" keyword and what it refers to.

## "this" keyword
> ***this*** refers to the object that is executing the current piece of code.

![this.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1652201034438/kBbR4iFGk.png align="left")

The above image depicts the Global execution context, it consists of the following:

* The global object: - In the browser, this is a window object.
* "this" keyword: - this is referring to the global object
* The variable environment: - a place in memory where variables live.
* The outer environment: -When we execute code within a function the outer environment is the code outside that function — at the global level, it is null.

"this" refers to different objects depending on how it is used:
 * In an object method, this refers to the object.
 * Directly, this refers to the global object.
 * In an event, this refers to the element that received the event.
 * In a function, this refers to the global object.
 * In a function, in strict mode, this is undefined.

For more details, check out mdn docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

## Call, Apply and Bind
> Call, Apply and Bind are the method in Javascript and basically used to control what
```
this
``` in a function points to. Also called function borrowing methods.

Function borrowing allows us to use the methods defined in one object on a different object without making a copy of the method.

### Implicit Binding
In JavaScript, implicit binding is already declared by the language. As shown in the code snippet below.

``` javascript
const fruit = {
  name: "mango",
  printFruit: function () {
    console.log(this.name)  // mango
  }
}
fruit.printFruit()
```
### Explicit Binding
In Explicit Binding, we explicitly point ```
this
``` of function to the object, both defined in the same level of scope.

``` javascript 
const fruit = {
  name: "mango",
}

function printFruit() {
    console.log(this.name)  // mango
  }

printFruit.call(fruit)
```
In the above code snippet, object and function are defined in the global environment, by using the call() method we explicitly point ```
this
``` of the function (printFruit) to the object (fruit).

### ```call()``` method
> In the ```call()``` method, the context with which the function has to be called is passed as a parameter to the call.

As shown In the fruit example above.

#### How to pass multiple parameters in the call() method?
In the same example of fruit, we can pass the arguments to the call method as shown in the snippet below:

Code snippet of the ```call()``` method:
``` javascript 
const fruit = {
  name: "mango",
}

function printFruit(fruit2, fruit3) {
    console.log(this.name, fruit2, fruit3)  // mango apple banana
  }

printFruit.call(fruit, "apple", "banana")
```
In the call() method, the first argument is the object with whose context the function is to be called and the following arguments are the values with are to be used in the function.

### apply() method
> ```apply()``` method is the same as the ```call()```, except the second argument is passed as an array of values.

Code snippet of the ```apply()``` method:
``` javascript 
const fruit = {
  name: "mango",
}

function printFruit(...args) {
    console.log(this.name, args[0], args[1])  // mango apple banana
  }

printFruit.apply(fruit, ["apple", "banana"])
```
This makes it easier as we need to pass an array as an argument.

### bind() method
> ```bind()``` method is similar to ```call()```, with one difference. Unlike the ```call()``` method invoking a function directly, the bind method returns the brand new function which can be stored and invoked as and when required.

Code snippet of the ```bind()``` method:
``` javascript 
const fruit = {
  name: "mango",
}

function printFruit() {
    console.log(this.name)  // mango 
  }

const storedFunction = printFruit.bind(fruit)

storedFunction()
```
Here, the ```printFruit.bind(fruit)``` return a brand new function, which is stored in ```storedFunction``` and invoked on the next line when required.

## Summary

* This keyword refers to different objects depending on how it is used.
* In the case of implicit binding, ```this``` binds to the object adjacent to the dot(.) operator while invoking the method.
* In the case of explicit binding, we can call a function with an object when the function is outside of the execution context of the object. This can be done using call(), apply() and bind(). 
