DEV Community

Ming-Shiuan Tsai
Ming-Shiuan Tsai

Posted on • Edited on

4 3

JavaScript: What is 'this'?

this is an useful but also confusing keyword. Here, I'll mainly introduce how it works in a function call.

In most cases, the value of this in a function depends on how the function is called. Let's take a look of some examples. If we write a program to increase the salary of an employee,

const employee = {
    name: 'Foo',
    salary: 1000,
    giveRaise: function(){
        this.salary = this.salary*1.03;
    }
}

employee.giveRaise();
console.log(employee)        
//result:
//{   
//    name:'foo',
//    salary:1030,
//    giveRaise:[Function:giveRaise]
//}

Enter fullscreen mode Exit fullscreen mode

Foo's salary changes from 1000 to 1030. this in the function is correctly bound to the employee object. However, if the function above is called in this way:

giveRaiseFunction = employee.giveRaise;
giveRaiseFunction();
console.log(employee);
//result:
//{
//    name: 'Foo',
//    salary: 1000,
//    giveRaise: [Function: giveRaise]
//}

Enter fullscreen mode Exit fullscreen mode

Unfortunately, Foo's salary is not increased. What happened is when the function,giveRaiseFunction(), is called, the function is not bound to any object. As a result, this will refer to the global object and in browser, it'll be window and there'll be no salary keyword in window. In some cases, if people use strict mode, this will be whatever it was set to when executing the context and the default will be undefined.

Now, that's consider another situation, if we need a more complicated function, we may need a function which calls the other functions. For example,

const employee = {
    name: 'Foo',
    salary: 1000,
    giveRaise: function(){
        const calculateIncrease = function(){
            //console.log(this);
            return this.salary*0.03
        }
    }
    //console.log(this);
    //console.log('-------------------------');
    this.salary = this.salary+calculateIncrease();
}

employee.giveRaise();
console.log(employee)

//result:
//{
//    name: 'Foo',
//    salary: NaN,
//    giveRaise: [Function: giveRaise]
//}

Enter fullscreen mode Exit fullscreen mode

This time, a strange result happened. Salary value is consider not a number. If we do console.log test to check what exactly happened, we'll find this keyword in calculateIncrease function is actually bound to global object instead of employee object.

In ES6, a new syntax to define a function is introduced -- arrow functions. When using arrow function syntax, the function doesn't have its own this binding. It remains the this value of the enclosing lexical context (arrow function's parent). In this way, this will refer to the parent's object which is employee in this example.

const employee = {
    name: 'Foo',
    salary: 1000,
    giveRaise: function(){
        const calculateIncrease = ()=>{
            return this.salary*0.03
        }
        this.salary = this.salary + calculateIncrease();
    }
}

employee.giveRaise();
console.log(employee)

//result:
//{
//    name: 'Foo',
//    salary: 1030,
//    giveRaise: [Function: giveRaise]
//}

Enter fullscreen mode Exit fullscreen mode

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (1)

Collapse
 
josegonz321 profile image
Jose Gonzalez

‘This’ = the context where the object was called in javascript

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more