'This' in Javascript
Tags: javascript, webdev, react, programming
Published: 2022-01-14 09:11:39

If you're a javascript developer, definitely you would've come across a mystery keyword **this**.


![Javascript this](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tliginau5jrig9l70zus.jpeg)

The keyword **this** can be major point of confusion, misery and general suffering in the life of a new JS developer.

Today we're going to see how **this** works in Javascript.

**Basic definition :**
 

> **this** refers to the object that is executing the current function (current execution scope)

There are 3 major use case scenarios where **this** keyword will be used.

1. In functions
2. Methods in objects and class
3. Global

It will be peculiar in each cases. Let's see it in detail.

## 1. In functions

Functions can be declared in different ways and most widely declared ways are function declarations and arrow functions.

**Function Declarations :**

```
function normalFunction() {
    console.log('regular function', this); // window
}
normalFunction();
```

If we try to call this function it will log the result of window i.e., global object which can be referred by **this** in javascript.

**this** will default to the global object, which is window in a browser and empty object in node.

```
function normalFunction() {
    'use strict';
    console.log('regular function', this); // undefined
}
normalFunction();
```

In strict mode, **this** value is not set when entering an execution context, it remains as **undefined**. Hence, it will log as **undefined**.

**Arrow Functions :**

```
const arrowFunction = () => {
    console.log('arrow function', this); // window
}

arrowFunction();
```
**Note**: Arrow functions don't have own version of **this**. They will always inherit from the parent.

What can we expect this to log? same as with normal functions, window or global object. Same result but with different reason. With normal functions the scope is bound to global object by default, arrows functions, as I said before, do not have their own **this** but they inherit it from the parent scope, in this case the global one.

What would happen if we add "use strict"? 

```
const arrowFunction = () => {
    'use strict';
    console.log('arrow function', this); // window
}

arrowFunction();
```

Nothing, it will log the same result, since the scope comes from the parent one.

## 2. Methods in objects and class 


**Methods in objects :**

Whenever we are calling functions inside object, it is known as method.

```
const user = {
    firstName: 'Naveen',
    lastName: 'chandar',
    normalFunction() {
        console.log('regular method',this); // user object
        return `${this.firstName} ${this.lastName}`;
    }
}
user.normalFunction(); //Naveen chandar
```
what would it show in console ? window (based on explanations given above). But it will log as **object user** itself because we're trying to access **this** inside methods in object, it will refer the object itself.

**Tip**: We should not see where **this** has been declared, we should see how the current function has been invoked. If it is invoked without any parent (left to the dot) Eg.user, **this** will be global object and if invoked with parent, it will scope to parent and returns the parent **this**.

What happens if you're trying to call arrow functions as methods inside objects ? 

```
const user = {
    firstName: 'Naveen',
    lastName: 'chandar',
    arrowFunction: () => {
        console.log('arrow method',this); //window
        return `${this.firstName} ${this.lastName}`;
    }
}
user.normalFunction(); //undefined undefined
```

What's the result expected ? Naveen chandar ?. No, It will be **undefined undefined**. As said earlier, Arrow functions doesn't has own **this**. No matter where you call arrow functions, It will always inherit from parent scope and return the parent **this**.

In this case, **user** is the parent and user has access to global object by default, it logged the value of window and if you expand the window object, there won't be any **firstName** or **lastName** binded to that, it return as **undefined undefined**.

This is why it's not recommended or not a good practice to write arrow functions as methods inside objects. But there are some rare scenarios where arrow functions will be helpful as methods.

**Methods in class :**

Let's see the same examples with classes. Classes are nothing but a template for creating objects.

```
class User {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    normalFunction() {
        console.log(this); // User obj
        return `${this.firstName} ${this.lastName}`;
    }
}
const newUser = new User('naveen', 'chandar');
console.log(newUser.normalFunction()); // naveen chandar
```

**Note**: If we are trying to access something with **new** keyword, Javascript will create an empty object by default.

The above code will give the result as expected, because of **new** keyword, empty object will be created and binded to the User object.

what happens if trying to use arrow functions as methods inside class ? 

```
class User {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    arrowFunction = () => {
        console.log(this); // User obj
        return `${this.firstName} ${this.lastName}`;
    }
}
const newUser = new User('naveen', 'chandar');
console.log(newUser.arrowFunction()); // naveen chandar
```
what's the result expected ? ** undefined undefined **?
No, It will return the same result as normal function. Because of lexical scoping.

## Conclusion

To summarise,

* **this** refers to the object that is executing the current function.

* When used in global, **this** refer to window itself.

* In normal functions **this** refers to how the function is invoked. (By default refers to global object).

* Arrow functions will always inherit from the parent.

* When used in object, **this** refer to object itself for normal functions.

* When used in object, **this** refer to global object for arrow functions.

* When used in class, **this** refer to object itself for both normal functions and arrow functions.


Thanks for reading this post. Hope, this post will make you understand how **this** works in JS 😎.

Let's meet on next post with another javascript concept.

Have a great day 🙂.