# Understanding Call, Bind and Apply Methods in JavaScript

***This article was originally published at:*** [***https://blog.bitsrc.io/understanding-call-bind-and-apply-methods-in-javascript-33dbf3217be***](https://blog.bitsrc.io/understanding-call-bind-and-apply-methods-in-javascript-33dbf3217be)

If you are learning JavaScript, you might have seen the `this` keyword. The `this` keyword in JavaScript behaves differently compared to other programming languages. This causes a lot of confusion for programmers.

In other object-oriented programming languages, the `this` keyword always refers to the current instance of the class. Whereas in JavaScript, the value of `this` depends on how a function is called.

Let’s look at some examples to demonstrate the behavior of `this` in JavaScript.

#### Example 1:

```javascript
const person = {  
  firstName: 'John',  
  lastName: 'Doe',  
  printName: function() {  
    console.log(this.firstName + ' ' + this.lastName);  
  }  
};
```

Now let’s execute the `printName` method.

```javascript
person.printName();
```

This prints:

```javascript
John Doe
```

Here, I am calling the `printName()` method using the `person` object, so the `this` keyword inside the method refers to the `person` object.

Let’s write the below snippet at the end of the above code.

```javascript
const printFullName = person.printName;  
printFullName();
```

What do you think the **console.log** will now output? Surprisingly, this prints:

```javascript
undefined undefined
```

**Why does this happen?**

Here, we are storing a reference of `person.printName` to `printFullName` variable. After that, we are calling it without an object reference, so `this` will now refer to the window (global) object or undefined (in strict mode).

If the script is in strict mode, `this` refers to `undefined`, so `console.log()` will return an error.

#### Example 2:

```javascript
const counter = {  
  count: 0,  
  incrementCounter: function() {  
    console.log(this);  
    this.count++;  
  }  
}

document.querySelector('.btn').addEventListener('click', counter.incrementCounter);
```

What would be the value of `this` inside `incrementCounter()` method?

In the above snippet, the `this` keyword refers to the DOM element where the event happened, not the `counter` object.

So we can see that the `this` keyword inside a function refers to different objects depending on how the function is called and sometimes we accidentally lose reference to the `this` variable. So how can we prevent that from happening?

### Call( ), Bind( ), and Apply( ) to Rescue

We use Call, Bind and Apply methods to set the `this` keyword independent of how the function is called. This is especially useful for the callbacks (as in the above example).

We know that functions are a special kind of objects in JavaScript. So they have access to the same methods and properties as objects. To prove functions are objects, we can do something like this, for example:

```javascript
function greeting() {  
  console.log('Hello World');  
}

greeting.lang = 'English';

// Prints 'English'  
console.log(greeting.lang);
```

JavaScript also provides some special methods and properties to every function object. So every function in JavaScript inherits those methods. Call, bind, and apply are some of the methods that every function inherits.

### Bind( )

The bind method creates a new function and sets the `this` keyword to the specified object.

#### Syntax:

```javascript
`function`.bind(thisArg, optionalArguments)
```

For example:

Let’s suppose we have two person objects.

```javascript
const john = {  
  name: 'John',  
  age: 24,  
};

const jane = {  
  name: 'Jane',  
  age: 22,  
};
```

Let’s add a greeting function:

```javascript
function greeting() {  
  console.log(`Hi, I am ${this.name} and I am ${this.age} years old`);  
}
```

We can use the `bind` method on the `greeting` function to bind the `this` keyword to `john` and `jane` objects. For example:

```javascript
const greetingJohn = greeting.bind(john);

// Hi, I am John and I am 24 years old  
greetingJohn();

const greetingJane = greeting.bind(jane);

// Hi, I am Jane and I am 22 years old  
greetingJane();
```

Here `greeting.bind(john)` creates a new function with `this` set to `john` object, which we then assign to `greetingJohn` variable.

We can also use `bind` in case of callbacks and event handlers. For example:

```javascript
const counter = {  
  count: 0,  
  incrementCounter: function() {  
    console.log(this);  
    this.count++;  
  }  
};

document.querySelector('.btn').addEventListener('click', counter.incrementCounter.bind(counter));
```

In the above example, the `this` keyword inside the `incrementCounter` method will now correctly refer to the `counter` object instead of the event object.

#### Bind() can also accept arguments

We can also pass extra arguments to the bind method. The general syntax for this is `function.bind(this, arg1, arg2, ...)`. For example:

```javascript
function greeting(lang) {  
  console.log(`${lang}: I am ${this.name}`);  
}

const john = {  
  name: 'John'  
};

const jane = {  
  name: 'Jane'  
};

const greetingJohn = greeting.bind(john, 'en');  
greetingJohn();

const greetingJane = greeting.bind(jane, 'es');  
greetingJane();
```

In the above example, the `bind` method creates a new function with certain parameters predefined (`lang` in this case) and `this` keyword set to the `john` and `jane` objects.

### Call ( )

The call method sets the `this` inside the function and immediately executes that function.

The difference between `call()` and `bind()` is that the `call()` sets the `this` keyword and executes the function immediately and it does not create a new copy of the function, while the `bind()` creates a copy of that function and sets the `this` keyword.

#### Syntax:

```javascript
`function`.call(thisArg, arg1, agr2, ...)
```

For example:

```javascript
function greeting() {  
  console.log(`Hi, I am ${this.name} and I am ${this.age} years old`);  
}

const john = {  
  name: 'John',  
  age: 24,  
};

const jane = {  
  name: 'Jane',  
  age: 22,  
};

// Hi, I am John and I am 24 years old  
greeting.call(john);

// Hi, I am Jane and I am 22 years old  
greeting.call(jane);
```

The above example is similar to the `bind()` example except that `call()` does not create a new function. We are directly setting the `this` keyword using `call()`.

#### Call () can also accept arguments

`Call()` also accepts a comma-separated list of arguments. The general syntax for this is `function.call(this, arg1, arg2, ...)`

For example:

```javascript
function greet(greeting) {  
  console.log(`${greeting}, I am ${this.name} and I am ${this.age} years old`);  
}

const john = {  
  name: 'John',  
  age: 24,  
};

const jane = {  
  name: 'Jane',  
  age: 22,  
};

// Hi, I am John and I am 24 years old  
greet.call(john, 'Hi');

// Hello, I am Jane and I am 22 years old  
greet.call(jane, 'Hello');
```

### Apply ( )

The `apply()` method is similar to `call()`. The difference is that the `apply()` method accepts an array of arguments instead of comma-separated values.

#### Syntax:

```javascript
`function`.apply(thisArg, [argumentsArr])
```

For example:

```javascript
function greet(greeting, lang) {  
  console.log(lang);  
  console.log(`${greeting}, I am ${this.name} and I am ${this.age} years old`);  
}

const john = {  
  name: 'John',  
  age: 24,  
};

const jane = {  
  name: 'Jane',  
  age: 22,  
};

// en
// Hi, I am John and I am 24 years old  
greet.apply(john, ['Hi', 'en']);

// es
// Hola, I am Jane and I am 22 years old  
greet.apply(jane, ['Hola', 'es']);
```

### Conclusion

We have learned how `this` keyword behaves differently in JavaScript than in other object-oriented languages. The call, bind and apply methods can be used to set the `this` keyword independent of how a function is called.

The bind method creates a copy of the function and sets the `this` keyword, while the call and apply methods set the `this` keyword and calls the function immediately.

That’s it and if you found this article helpful, please click the like 🙂 button, you can also follow me on [Hashnode](https://hashnode.com/@SukhjinderArora), [Medium](https://medium.com/@sukhjinder) and [Twitter](https://twitter.com/_sukh_arora), and if you have any doubt, feel free to comment! I’d be happy to help :)
