DEV Community

Ming-Shiuan Tsai
Ming-Shiuan Tsai

Posted on • Updated on

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

Discussion (1)

Collapse
josegonz321 profile image
Jose Gonzalez

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