# JavaScript: this is easy and what do you need to know about it!

# Introduction
Let me start this article by thanking the readers of my series,  [JavaScript: Cracking the Nuts](https://hashnode.com/series/javascript-cracking-the-nuts-ckawn7vc5007dl6s164ogqplz) for liking and loving it so far. This article will go through another fundamental but equally misunderstood aspect of JavaScript called the `this` keyword.

> It is not mandatory, but if you are new to the  [series](https://hashnode.com/series/javascript-cracking-the-nuts-ckawn7vc5007dl6s164ogqplz), I would recommend you to go through the previous articles for other fundamental concepts like,
- [JavaScript Interpreted or Compiled? The Debate is Over](https://blog.greenroots.info/javascript-interpreted-or-compiled-the-debate-is-over-ckb092cv302mtl6s17t14hq1j)
- [Understanding JavaScript Execution Context like never before](https://blog.greenroots.info/understanding-javascript-execution-context-like-never-before-ckb8x246k00f56hs1nefzpysq)
- [JavaScript Hoisting Internals](https://blog.greenroots.info/javascript-hoisting-internals-ckbuavl6f00dllas14hl9ckq1)

Alright, so let us get started. At the end of the article, you should have a better understanding with,
- What is **this** in JavaScript.
- How to make **this** sounds less confusing than ever.
- Rules of **this** and the usage.
- Importantly, **this** is easy!

> Many Thanks to the resource links mentioned in the [Credits and Resources](https://blog.greenroots.info/javascript-this-is-easy-and-what-do-you-need-to-know-about-it#heading-credits-and-resources) section. It helped me to master this concept well.

# Lengthy Read Alert ⚠️
Unlike other articles from the series, this one is going to be a bit lengthy. After going over several tutorials, I felt that one should connect various aspects to understand the concept of `this` well. For example, the concept of `call => apply => bind` is very related to understanding `this` keyword. We need to discuss them together.

I could have broken things into multiple articles but, it is better to be together as the concepts are very inter-related. Hence the lengthy read alert! 

Take your favorite beverages, relax, and start reading. I am sure you are going to enjoy it.

# What is `this`?
`this` is a keyword in JavaScript, and the existence of it is to allow us in,
- To understand different execution [contexts](https://blog.greenroots.info/understanding-javascript-execution-context-like-never-before-ckb8x246k00f56hs1nefzpysq).
- The context of the object that `this` is related to.

Remember that, when an [Execution Context](https://blog.greenroots.info/understanding-javascript-execution-context-like-never-before-ckb8x246k00f56hs1nefzpysq) is created in JavaScript, it creates a special thing called, `this`. 

- In the Global execution context, **this** is equal to the global `window` object.
- In the Function execution context, the value of **this**  depends on `binding`.

# Rules of Binding
It can be challenging to understand a function's `this` keyword as it behaves differently in JavaScript than in other languages.  When it comes to finding the context of `this`, we need to see where the function is invoked.

The usage of `this` can be categorized into four different binding aspects.

## Implicit binding
Implicit binding is the most used use-case for the `this` keyword. When we invoke a method of an object, we use the dot(.) notation to access it. In the case of implicit binding, the context of `this` is bound to the object on which we invoke the method. 

Here is an example,

**Example:**
```js
const user = {
    name: 'GreenRoots',
    address: 'HashNode',
    greeting: function() {
        return `Hello, ${this.name} belongs to ${this.address}`
    }
};

user.greeting();
```
**Explanation:**
In the above example, we invoke the `greeting()` method on the user object using the dot(.) notation. Hence `this` is bound to the user object. So, `this.name` is going to log `GreenRoots` and `this.address` is `HashNode`.

Let's take another example to explain this concept better way,

**Example:**
```js
 function greeting(obj) {
      obj.logMessage = function() {
          console.log(`${this.name} is ${this.age} years old!`);
      }
  };

  const tom = {
      name: 'Tom',
      age: 7
  };

  const jerry = {
      name: 'jerry',
      age: 3
  };

  greeting(tom);
  greeting(jerry);

  tom.logMessage ();
  jerry.logMessage ();
```
**Explanation:**
In the above example, we have two objects, `tom` and `jerry`. We have decorated(enhanced) these objects by attaching a method called `logMessage ()`. 

Just notice when we invoke `tom.logMessage()`, the method is invoked on the `tom` object. Hence `this` bound to the `tom` object. The same applies when `jerry.logMessage ()` is invoked.

## Explicit binding
We are aware that JavaScript creates an environment to execute the code we write. This environment includes stuff beyond the actual code we write.

It takes care of the memory creation for variables, functions, objects, etc., in the creation phase. Finally, execute the code in the execution phase. This special environment is called `JavaScript Execution Context`.

There are many such environments(Execution Contexts) in a JavaScript application. Each Execution Context is independent of the other. But we may want to access something from one execution context to another. That is where explicit binding comes into play. We can bind stuff from one context into the context of a different environment for execution using **this**. 

There are three extraordinary methods, `call()`, `apply()`, and `bind()`, help in achieving explicit binding.

### call() method
With the call() method, the context with which the function has to be called will be passed as a parameter to the call(). Let us see with an example,

**Example:**
```js
greeting: function() {
        return `Hello, ${this.name} belongs to ${this.address}`
 }

const user = {
   name: 'GreenRoots',
   address: 'HashNode'  
 };

 greeting.call(user); 
```
**Explanation:**
What we see here is, the call() method is invoked on a function called greeting(). The greeting() function just logs a message using `this.name` and `this.address`. But what is `this` here? That gets determined by what has been passed to the call() method.

Here `this` will bind to the user object because we have passed the user as a parameter to the call() method. Hence `this.name` should log the value of the user object's name property, i.e., GreenRoots, and similarly, `this.address` as Hashnode.

In the above example, we have passed just one argument to call(). But, we can pass multiple arguments to call(),  if required. Let's take another example to understand that,

**Example**
```js
var getName = function(hobby1, hobby2) {
     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
 }
 var user = {
   name: 'Tapas',
   address: 'Bangalore'  
 };

 var hobbies = ['Swimming', 'Blogging'];
 getName.call(user, hobbies[0], hobbies[1]); 
```
**Explanation:**
Notice that we have passed two more arguments here in the call() method. The first argument must be the object context with which the function has to be invoked. Other parameters could be just values to use. Here I am passing *Swimming* and *Blogging* as two parameters to the getName() function.

Do you notice a pain point here? In case of a call(), the arguments need to be passed one by one, which is not such a smart way of doing things! That's where our next method apply() comes into the picture.

### apply() method
The hectic way of passing the arguments to the call() method can be solved by another alternate method called apply(). It is the same as `call()` but allows passing the arguments more conveniently. Have a look,

**Example**
```js
var getName = function(hobby1, hobby2) {
     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
 }
 var user = {
   name: 'Tapas',
   address: 'Bangalore'  
 };

 var hobbies = ['Swimming', 'Blogging'];
 getName.apply(user, hobbies);
```
**Explanation:**
As you see here, we can pass an array as arguments, which is much more convenient than passing one by one.

> When you have only one value argument or no value arguments to pass, use call(). When you have multiple value arguments to pass, use apply().

### bind() method
The `call()` method invokes the function by passing the context of `this`. The `bind()` method is similar to the `call()` but, instead of calling the function directly, bind() returns a brand new function, and we can invoke that instead.

**Example:**
```js
var getName = function(hobby1, hobby2) {
     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
 }
 var user = {
   name: 'Tapas',
   address: 'Bangalore'  
 };

 var hobbies = ['Swimming', 'Blogging'];
 var newFn = getName.bind(user, hobbies[0], hobbies[1]); 

 newFn();
```
**Explanation:**
As we see above, the `getName.bind()` doesn't invoke the function getName(). It returns a new function, newFn and we can invoke is as, newFn().

## new binding
A Constructor function is created with the `new` keyword. Here is an example of a Constructor function,

```js
var Cartoon = function(name, animal) {
     this.name = name;
     this.animal = animal;
     this.log = function() {
         console.log(this.name +  ' is a ' + this.animal);
     }
 };
```

We can create the objects using the `new` keyword as,

```js
 var tom = new Cartoon('Tom', 'Cat');
 var jerry = new Cartoon('Jerry', 'Mouse');
```
Let's break it down. Take this line,

```js
var tom = new Cartoon('Tom', 'Cat');
```
Here the function `Cartoon` is invoked with the `new` keyword. Hence `this` will be bound to the new object created here, `tom`.

## Global Object binding
What will be the output of this code execution? What is `this` bind to here?

```js
var sayName = function(name) {
    // 'use strict';
    console.log(this.name);
};

window.name = 'Tapas';
sayName();
```
if the `this` keyword is not resolved with any of the above bindings, `implicit`, `explicit` or `new` then, the `this` binds to the window(global) object.

## Arrow functions, no binding?
ES6 introduced [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), which don't provide their own `this` binding. As we have seen so far, in regular functions, the `this` keyword represented the object that is called the function, which could be the window, the document, user-defined, or whatever. 

Arrow functions don't bind their own scope but inherit it from the parent. 

Example time. Let us see it working.

```js
var testHobbies = {
  hobbies: ['Cricket', 'Football', 'Blogging'],
  name: 'Alex',
  logHobbies() {
     this.hobbies.forEach((elem) => {
     console.log(`${this.name} knows ${elem}`);
  });
  }
}
```
Here the logHobbies() method iterates through the hobbies and logs them into the console. Notice, we are using an arrow function in `forEach`. The `this` inside the arrow function would bind to the object `testHobbies` as there is no `this` binding for the arrow functions, and it always binds to the parent one. 

Hence invoking testHobbies.logHobbies() would correctly log as,

```shell
Alex knows Cricket
Alex knows Football
Alex knows Blogging
```
Now let us bring a twist to it. Notice the modification I have made below. Instead of an arrow function, the for-each uses a regular function.

```js
var testHobbies = {
  hobbies: ['Cricket', 'Football', 'Blogging'],
  name: 'Alex',
  logHobbies() {
    this.hobbies.forEach(function(elem){
    console.log(`${this.name} knows ${elem}`);
  });
  }
}
```
What do you think, `this` would be bound to here inside forEach? It is not an arrow function. It is a regular function, and it has its own execution context. In that execution context, there is nothing called a name. Hence `this.name` is undefined.

Hence the output will be,

```shell
undefined knows Cricket
undefined knows Football
undefined know Blogging
```
We will see it in more detail in future articles on `Scope` and `Closure`.

# Use Strict and this
Normally, in global scope `this` keyword refers to window object,

```js
<script>
console.log(this);  //returns window object.
</script>
```
In JavaScript strict mode also, the `this` keyword in global scope returns window object. However, it behaves differently in the function scope. 

See the following example,

```js
<script>
        "use strict;"
        console.log(this);

        function testThis() {
            "use strict";
            console.log('testThis', this);
        }

        testThis();
    </script>
```
It will log the following output in the console,

```bash
Window {parent: Window, opener: null, top: Window, length: 0, frames: Window, …}
testThis undefined
```


# Conclusion
Yes, Understanding `this` is easy! But at the same time, it could be challenging to comprehend the rules and usage of `this`. We will understand `this` better when we focus on the question, `Where is the function invoked`? 

In most of the cases, the usage would be with Implicit Binding. There will be used with explicit binding with the call(), apply(), and bind(). With many of the JavaScript-based frameworks like Reactjs, Angular, etc., we use arrow functions.

Just note, as long as you have these rules understood and practiced, I am sure you will agree that `this` is really easy to work with!

# Credits and Resources
- [A short YouTube video from uidotdev](https://youtu.be/zE9iro4r918)
- [MDN site](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) about `this`.
- The cover photo is built on top of an awesome image created by [brgfx on freepik](https://www.freepik.com/brgfx).

# Other Useful Resources on `this`
- [What is this in JavaScript](https://blog.skay.dev/what-is-this-in-javascript)
- [How to Eyeball Your ‘This’ Context in Javascript](https://gist.github.com/zcaceres/2a4ac91f9f42ec0ef9cd0d18e4e71262)

%[<HR />]
I hope you find the article useful. Please Like/Share so that it reaches others as well. If you enjoyed this article or found it helpful, let's connect. You can find me on [Twitter(@tapasadhikary)](https://twitter.com/tapasadhikary) sharing thoughts, tips, and code practices.

To get e-mail notifications on my latest posts, please ***subscribe*** to my blog by hitting the Subscribe button at the top of the page.

I'll explain other fundamental concepts called `Scope` and `Closure` in the series's future posts. Stay Tuned.
