Skip to content
Related Articles
Open in App
Not now

Related Articles

this in JavaScript

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 29 Sep, 2022
Improve Article
Save Article

 this keyword in javascript always holds the reference to a single object, that defines the current line of code’s execution context. Functions, in JavaScript, are essentially objects. Like objects, they can be assigned to variables, passed to other functions, and returned from functions. And much like objects, they have their own properties. One of these properties is this.

The value that this store is the current execution context of the JavaScript program. Thus, when used inside a function this value will change depending on how that function is defined, how it is invoked and the default execution context. this keyword will refer to different objects depending upon how it is used. 

Functions, in JavaScript, can be invoked in multiple ways  :

this with function invocation:

Function invocation refers to the process of invoking a function using its name or an expression that evaluates the function object followed by a set of opening and closing first brackets(the inclusion of the brackets indicates that we are asking the JavaScript engine to execute the function immediately).
For instance: 
 

JavaScript




<!DOCTYPE html>
<html>
<body>
<script>
    function doSomething() {
        // do something here
    }
 
// function invocation
doSomething();
</script>                   
</body>
</html>

this inside the doSomething function, if it is invoked through the function invocation as above, has the value of the global object, which is the window object in the browser environment:
 

JavaScript




<!DOCTYPE html>
<html>
<body>
<script>
    function doSomething(a, b) {
 
       // adds a propone property to the Window object
        this.propone = "test value";
    }
 
// function invocation
doSomething();
document.write(window.propone);
</script>                   
</body>
</html>                       

Output:  

test value 

However, this is not always the case. If the doSomething() function were running in strict mode, it would log undefined instead of the global window object. This is because, in strict mode(indicated by the line: ‘use strict’;), the default value of this, for any function object, is set to undefine instead of the global object. 

For example :  

JavaScript




<!DOCTYPE html>
<html>
<body>
<script>
    function doSomething() {
        // enable the strict mode
        'use strict';
 
       // logs undefined
        document.write(this + '<br>')
            function innerFunction() {
              // Also logs undefined, indicating that
              // strict mode permeates to inner function scopes
                document.write(this)
            }
        innerFunction();
    }
 
// function invocation
doSomething();
</script>                   
</body>
</html>                                          

Output:  

undefined
undefined 

this with method invocation:

Functions, when defined as fields or properties of objects, are referred to as methods. 

JavaScript




<!DOCTYPE html>
<html>
<body>
<script>
    let person = {
        name : "John",
        age : 31,
        logInfo : function() {
            document.write(this.name + " is " + this.age + " years old ");
        }
    }
       // logs John is 31 years old
       person.logInfo()
                 </script>                   
</body>
</html>                                       

Output:  

John is 31 years old 

In the above code example, logInfo() is a method of the person object and we invoked it using the object invocation pattern. That is, we used the property accessors to access the method which was part of the object.
Such an invocation requires the use of an expression that evaluates the object which our method is a part, and a property accessor(Eg: person.logInfo()) followed by a set of opening and closing parentheses. It is essential to understand how to function invocations and method invocations differ. 

This in turn will help us understand what this context might be in any given function because, in each of these invocations, the value of this is different.
Inside such a method, that has been invoked using the property accessors, this will have the value of the invoking object, that is this will point to the object that was used in conjunction with the property accessor to make the call.

For example :  

JavaScript




<script>
    let add = {
        num : 0,
        calc : function() {
     
            // logs the add object
            document.write(this + ' ')
                this.num
                += 1;
            return this.num;
        }
    };
     
    // logs 1
    document.write(add.calc() + '<br>');
    // logs 2
    document.write(add.calc());
</script>

Output:  

[object Object] 1
[object Object] 2 

In the above example, calc() is a method of the additional object and is therefore called using the method invocation rules in lines 9 and 10. 
And we know, when method invocation patterns are used, the value of this is set to the calling object. Inside this calc() method, the value of this is set to the calling object, which in our case is added. and thus we can successfully access add’s num property. 

However, let us now look at one major confusion point: What happens to this in a function nested inside a method of an object? 

JavaScript




<script>
    let add = {
        num : 0,
        calc : function() {
     
        // logs the add object
        document.write(this + ' ')
     
        function innerfunc() {
            this.num += 1;
     
        // logs the window object
        document.write(this + ' ');
     
        return this.num
     
    } return innerfunc();
     }
    };
     
    // logs NaN
    document.write(add.calc() + '<br>');
     
    // logs NaN
    document.write(add.calc());
</script>

Output:  

[object Object] [object Window] NaN
[object Object] [object Window] NaN 

Let’s try to understand what just happened. When we call calc() in lines 14 and 15 we are using method invocation which sets this to add in calc(). This can be verified using the log statement in line 4.
However, innerfunc() is called from within the calc() method using a simple function invocation(line 11 ). This means, inside innerfunc() this is set to the global object, which does not have a num property, and hence the NaN outputs are obtained.

How do we solve this issue? How can we retain the value of this from the outer method inside the nested function?

One solution is to assign this value from the outer function to a variable to be used in the nested function like so: 

JavaScript




<script>
    let add = {
        num : 0,
        calc : function() {
 
            // logs the add object
            document.write(this + ' ')
 
           // using thisreference variable to
           // store the value of this
           thisreference = this;
 
            function innerfunc()
            {
 
             // using the variable to access the
             // context of the outer function
                thisreference.num += 1;
 
               // logs the add object
                document.write(thisreference + ' ');
                return thisreference.num;
            }
            return innerfunc();
        }
    };
    // logs 1
    document.write(add.calc() + '<br>');
 
    // logs 2
    document.write(add.calc());
</script>                                                                

Output:  

[object Object] [object Object] 1
[object Object] [object Object] 2 

Other solutions to this problem involve using bind(), call(), or apply(), which we will soon look into.

this with constructor invocation:

Constructor invocation is performed when a new keyword is followed by a function name, and a set of opening and closing parentheses(with or without arguments).

For example: let person1= new People(‘John’, 21); 

Here, person1 is the newly created object and People is the constructor function used to create this object. The constructor invocation is one of the several ways of creating objects in JavaScript. What exactly happens when we use the new keyword in conjunction with a function name? – There are essentially five steps involved in creating an object through this method. 

Let us study them with the following example: 

JavaScript




<script>
    let people = function(name, age) {
             this.name = name;
             this.age = age;
     
        this.displayInfo = function() {
           document.write(this.name + " is " + this.age + " years old");
          }
        }
     
    let person1
        = new people('John', 21);
     
    // logs John is 21 years old
    person1.displayInfo();
</script>

Output:  

John is 21 years old 
  • Firstly, an empty object is created that is an instance of the function name used with new(i.e : people(name, age)). In other words, it sets the constructor property of the object to the function used in the invocation(people(name, age)).
     
  • Then, it links the prototype of the constructor function(people) to the newly created object, thus ensuring that this object can inherit all properties and methods of the constructor function 
     
  • Then, the constructor function is called on this newly created object.If we recall the method invocation, we will see that is similar.Thus, inside the constructor function, this gets the value of the newly created object used in the call. 
     
  • Finally, the created object, with all its properties and methods set, is returned to person1 
     

Supported Browser:

  • Google Chrome
  • Microsoft Edge
  • Firefox
  • Opera
  • Safari

My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!