DEV Community

Cover image for 'This' in Javascript
Naveenchandar
Naveenchandar

Posted on

'This' in Javascript

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

Javascript this

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();
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 🙂.

Top comments (0)