# The Magic of this, call(), apply(), and bind() in JavaScript

**What** `this` **means in JavaScript** ?

this keyword refers to the context where piece of code is supposed to runs , functions or objects. this keyword represent global object . Global object (value of this) of browser is window and for node it is empty object.

### `this` **inside normal functions**

Arrow function does not have reference of this keyword.

```javascript
let obj = {
 name : "ram",
 callname(){
   console.log(`${this.name} name called`);
 },
 calarrow: ()=>{
  console.log(`${this.name} name called`);
 }
};

obj.callname();
obj.calarrow();

// ram name called
// undefined name called
```

Note - Regular nested function does not inherit this but nested arrow function inherit this.

```javascript
const actor = {
  name : "Ram",
  bow(){
    return `${this.name} takes a bow`;
  }
}
const detachedbow = actor.bow;
console.log(detachedbow());

// output = undefined takes a bow

console.log(typeof this); // object 
```

```javascript
const obj = {
   crew : "spot girls",
   prepareprops(){
     console.log(`Outer this.crew : ${this.crew}`);
     function arrangechairs(){
      console.log(`Inner this.crew : ${this.crew}`);
     }
     arrangechairs();
     const arrangelight = ()=>{
      console.log(`Arrow this.crew : ${this.crew}`);
     }
     arrangelight();
   },
}
obj.prepareprops();

// Output 
// Outer this.crew : spot girls
// Inner this.crew : undefined
// Arrow this.crew : spot girls
```

Javascript has some its own methods like this , call , apply and bind.

Detached methods - When we assign object methods to some variable or pass it like a callback function by removing from their original context , then we called it as detached method.

```javascript
const actor = {
  name : "Ram",
  bow(){
    return `${this.name} takes a bow`;
  }
}
const detachedbow = actor.bow;
console.log(detachedbow());

// output = undefined takes a bow

console.log(typeof this); // object 
```

In detached method, it has not reference of this keyword.

## What `call()` does

Immediately invokes the function and accepts argument individually in a comma-separated list.

```plaintext
function cookdish(ingredient, style){
    return `${this.name} prepare ${ingredient} in ${style} style!`
}
const sharmakitchen = {name : "sharma ji kitchen"}
const guptakitchen = {name : "gupta ji kitchen"}

console.log(cookdish.call(sharmakitchen , "Paneer and spices" , "mugli"));

// output - Sharma ji kitchen prepares Paneer and spices in mugli Style!
```

## What `apply()` does-

Immediately invokes the function and accepts arguments as a single array like object. It runs the function setting this = context and using an array like object args as a list of arguments. The only syntax difference between call and apply is that call expects a list of arguments, while apply takes an array-like object with them.

There is only a

```javascript
const guptaorder = ["chole kulche", "Punjabi dhabha"]
console.log(cookdish.apply(guptakitchen, guptaorder));

// output - Gupta ji kitchen prepares chole kulche in Punjabi dabha Style!
```

Delaying decorator -

```javascript
function f(x) {
  console.log(x);
}

function delay(f , ms){
  return function(args){
    setTimeout(()=>{
      f.apply(this , args);
    } , ms)
  }
}

let f1000 = delay(f, 1000);
let f1500 = delay(f , 1500);

f1000("test");
f2000("test");
```

## What `bind()` does

It returns a new function with the specified this value . Method `func.bind(context, ...args)` returns a “bound variant” of function `func` that fixes the context `this` and first arguments if given. The exotic bound function object returned by `f.bind(...)` remembers the context (and arguments if provided) only at creation time.

A function cannot be re-bound.

```javascript
function reportdelivery(location, status){
   return `${this.name} at ${location}:${status}`;
}

const deliveryboy = { name : "Ranveer"};
 console.log("call:", reportdelivery.call(deliveryboy, "Lyari", "Ordered"));
 console.log("apply: " , reportdelivery.apply(deliveryboy , ["Mars", "Pick up"]));
 console.log("Bind : " , reportdelivery.bind(deliveryboy , "Haridwar" , "What"));

// Output
// call: Ranveer at Lyari:Ordered
// apply:  Ranveer at Mars:Pick up
// Bind :  [Function: bound reportdelivery]

const bindreport =  reportdelivery.bind(deliveryboy , "Haridwar" , "What");
console.log(bindreport());

// Ranveer at Haridwar:What
```

## Difference between call, apply, and bind

![](https://cdn.hashnode.com/uploads/covers/695ca828e54aa5b95fde28b1/869d0ae5-be49-481b-b4a0-1736a8de15b1.png align="center")
