What exactly is 'this'? Understanding JavaScript's Call(), Bind(), and Apply() methods.
Tags: javascript
Published: 2022-07-27 14:35:12

---
title: What exactly is 'this'? Understanding JavaScript's Call(), Bind(), and Apply() methods.
published: true
date: 2022-06-03 14:08:13 UTC
tags: #javascript
canonical_url: https://okosunmary.hashnode.dev/what-exactly-is-this-understanding-javascripts-call-bind-and-apply-methods
---

A commonly used keyword in some programming languages is `this`. This term allows you to refer to an object from within it. One of the more perplexing aspects of Javascript is that `this` value varies based on the context in which it is invoked.

It refers to the **global scope** by default, but it refers to the function when invoked within it. We'll learn about the `this` keyword, as well as why and when to utilize **call** , **bind** , and **apply** in JavaScript, in this article.

> The value of this is assigned when a method or function is called. And NOT where it is defined!

```
const myLanguages = {
  firstLanguage:"Javascript",
  secondLanguage: "Python",
  language() {
    return `I code in ${this.firstLanguage} and ${this.secondLanguage}`;
  }
}

```

In the example above, the method `language()` has access to the properties of its object `myLanguages`, and therefore the `this` is function-scoped in this situation. In this scenario, `myLanguages.language()` would return as shown below.

```
myLanguages.language(); //I code in Javascript and Python

```

In another scenario, let us assign the method to the variable `globalScope`. If we try to console this variable, we can see that the `this` is no longer accessible within the `myLanguages` object; instead, it is now global scoped and it is now pointing to the window object and it would return an `undefined` because `firstLanguage` and `secondLangauge` are not available globally.

```
const globalScope = myLanguages.language
console.log(globalScope()) //I code in undefined and undefined

```

However, if we set a `firstLanguage` and `secondLangauge` property to the window object, we can now access both properties globally using the method of the `myLanguages` object.

```
window.firstLanguage = "Laravel";
window.secondLanguage = "Golang";
console.log(globalScope()) //I code in Laravel and Golang

```

So again, to reiterate, the value of `this` is assigned only when a method or function is called, not when it is defined. Although the `this` keyword was specified within the scope of the function, its value was allocated at the point where it was invoked in our example.

Now that we have a fundamental knowledge of how the `this` concept works, we can now delve into the call, bind, and apply methods as these concepts would help solve the issue of `this` scope.

Using these predefined methods, we can assign the value of `this` to whatever we want as they can be used to set the `this` keyword independent of how a function is called.

### Call()

This is a method that is predefined in JavaScript. It's used to call or invoke a method that takes the owner object as an argument. An object can use a method that belongs to another object by using the `call()` function. You can write a method once and then call it from another object without having to rewrite the method.

The format for a call() method can be seen as:

```
Object.function.call(this.Args)

```

In the example below, we have two objects `relation1` and `relation2` that can access the method `faveRelation` and we utilize the `call()` method with the owner object as its argument to scope `this` to be particular for each object.

```
const person = {
 faveRelation() {
 return `${this.name} is my favourite ${this.relation}`;
 }
}
const relation1 = {
 name:"Jamie",
 relation: "uncle"
}
const relation2 = {
 name:"Austin",
 relation: "nephew"
}
person.faveRelation.call(relation1); //Jamie is my favourite uncle
person.faveRelation.call(relation2); //Austin is my favourite nephew

```

The `call()` method accepts arguments as well. These arguments are comma-separated. They will be passed to the function call.

The format for a call() method with arguments can be seen as :

```
Object.function.call(this.Args, argument1, argument2, ...)

```

The code below is similar to what we had before, except it now includes method arguments.

```
const person = {
 faveRelation(city, country) {
 return `${this.name} is my favourite ${this.relation} and he lives in ${city},${country}`;
 }
}
const relation1 = {
 name:"Jamie",
 relation: "uncle"
}
const relation2 = {
 name:"Austin",
 relation: "nephew"
}
person.faveRelation.call(relation1, "Lagos", "Nigeria"); //Jamie is my favourite uncle and he lives in Lagos,Nigeria
person.faveRelation.call(relation2, "Benin-city", "Nigeria"); //Austin is my favourite nephew and he lives in Benin-city,Nigeria

```

### Apply() Method

The `apply()` method is similar to the `call()` method. The distinction is that the `call()` method takes individual parameters, whereas the `apply()` method takes an array of arguments. A `TypeError` will occur if this is not done.

The format for an apply() method with arguments can be seen as :

```
Object.function.call(this.Args, [argument1, argument2, ...])

```

> The apply() method is very handy if you want to use an array instead of an argument list.

If you had an array of numbers, say [1, 2, 3], and you want to determine the largest number, you could use this method. You'd utilize the `apply()` method with the array of integers as an argument, using the `Math` object and the `max` method. Because we don't have an object to refer to, the **null** keyword is used.

The **null** value is used in JavaScript to represent the intentional absence of any object value.

```
console.log(Math.max.apply(null,1,2,3)) // TypeError
console.log(Math.max.apply(null,[1,2,3])) // 3

```

Using the example below, let us see how the `apply()` method is used.

```
const person = {
 faveRelation: function(city, country) {
 return `${this.name} is my favourite ${this.relation} and he lives in ${city},${country}`;
 }
}
const relation1 = {
 name:"Jamie",
 relation: "uncle"
}
const relation2 = {
 name:"Austin",
 relation: "nephew"
}
person.faveRelation.apply(relation1, ["Lagos", "Nigeria"]); //Jamie is my favourite uncle and he lives in Lagos,Nigeria
person.faveRelation.apply(relation2, ["Benin-city", "Nigeria"]); //Austin is my favourite nephew and he lives in Benin-city,Nigeria

```

### Bind() method

The `bind()` method, unlike the `call()` and `apply()` methods, does not instantly execute the function. It simply returns a new version of the function whose `this` sets to argument `thisArg` .

The format for a bind() method can be seen as :

```
const bound = Object.function.bind(thisArgs);
bound()

```

In the example below, we called the `bind()` method of the `person.faveRelation()` method and pass in the `relation1` as its argument. The `boundFavePerson()` function is then called.

```
const person = {
 faveRelation: function() {
 return `${this.name} is my favourite ${this.relation}`;
 },
 favAnimal: function(hobby, animal) {
 return `${this.name} enjoys ${hobby} and loves ${animal}`;
 }
}
const relation1 = {
 name:"Jamie",
 relation: "uncle"
}
const relation2 = {
 name:"Austin",
 relation: "nephew"
}
const boundFavePerson = person.faveRelation.bind(relation1); 
console.log(boundFavePerson()); //Jamie is my favourite uncle

```

You can call the `bind()` method by passing the arguments directly or passing the arguments in the bound function itself.

You can either pass the arguments directly to the `bind()` method (Method1) or pass the arguments to the `bound` function itself (Method2).

The format for a bind() method with arguments can be seen as :

```
//Method1
const bound = Object.function.bind(thisArgs, argument1, argument2);
bound()

//Method2
const bound = Object.function.bind(thisArgs);
bound(argument1, argument2)


//Arguments passed directly
const boundPerson = person.favAnimal.bind(relation1, "surfing", "dogs"); 
console.log(boundPerson()); //Jamie enjoys surfing and loves dogs.

//Arguments passed in the bound function itself
const boundPerson1 = person.favAnimal.bind(relation2); 
console.log(boundPerson1("reading", "cats")); //Austin enjoys reading and loves cats

```

### Conclusion

From this article, we have learned:

- How the `this` keyword is scoped in Javascript.

- When a method or function is invoked, the value of `this` is assigned, not when it is defined.

- We also learned how to set the `this` keyword regardless of how a function is invoked using the call, bind, and apply methods.

If you found this article useful, please share it with your network, and if you have any comments, please drop them! I'd be delighted to help 🙂

### References

- https://www.javascripttutorial.net/javascript-this/

- https://betterprogramming.pub/understanding-the-this-keyword-in-javascript-cb76d4c7c5e8?gi=6ff6675c03cf

- https://betterprogramming.pub/when-to-use-bind-call-and-apply-in-javascript-1ae9d7fa66d5

- https://medium.com/@omergoldberg/javascript-call-apply-and-bind-e5c27301f7bb