this in JavaScript:

The this keyword is one of the most widely used and yet confusing keyword in JavaScript. Here, you will learn everything about this keyword.

this points to a particular object. Now, which is that object is depends on how a function which includes 'this' keyword is being called.

Look at the following example and guess what the result would be?

  
<script>

var myVar = 100;

function WhoIsThis() {
    var myVar = 200;

    alert(myVar); // 200
    alert(this.myVar); // 100
}

WhoIsThis(); // inferred as window.WhoIsThis()

var obj = new WhoIsThis();
alert(obj.myVar); 
</script>

The following four rules applies to this in order to know which object is referred by this keyword.

  1. Global Scope
  2. Object's Method
  3. call() or apply() method
  4. bind() method

Global scope:

If a function which includes 'this' keyword, is called from the global scope then this will point to the window object. Learn about global and local scope here.

Example: this keyword
  
<script>

var myVar = 100;

function WhoIsThis() {
    var myVar = 200;

    alert("myVar = " + myVar); // 200
    alert("this.myVar = " + this.myVar); // 100
}

WhoIsThis(); // inferred as window.WhoIsThis()

</script>

In the above example, a function WhoIsThis() is being called from the global scope. The global scope means in the context of window object. We can optionally call it like window.WhoIsThis(). So in the above example, this keyword in WhoIsThis() function will refer to window object. So, this.myVar will return 100. However, if you access myVar without this then it will refer to local myVar variable defined in WhoIsThis() function.

The following figure illustrates the above example.

this in JavaScript
Note : In the strict mode, value of 'this' will be undefined in the global scope.

'this' points to global window object even if it is used in an inner function. Consider the following example.

Example: this keyword inside inner function
  
var myVar = 100;

function SomeFunction() {

    function WhoIsThis() {
        var myVar = 200;

        alert("myVar = " + myVar); // 200
        alert("this.myVar = " + this.myVar); // 100
    }

    WhoIsThis(); 
}

SomeFunction();

So, if 'this' is used inside any global function and called without dot notation or using window. then this will refer to global object which is default window object.

this inside object's method:

As you have learned here, you can create an object of a function using new keyword. So, when you create an object of a function using new keyword then this will point to that particular object. Consider the following example.

Example: this keyword
  
var myVar = 100;

function WhoIsThis() {
    this.myVar = 200;
}
var obj1 = new WhoIsThis();

var obj2 = new WhoIsThis();
obj2.myVar = 300;

alert(obj1.myVar); // 200 
alert(obj2.myVar); // 300 

In the above example, this points to obj1 for obj1 instance and points to obj2 for obj2 instance. In JavaScript, properties can be attached to an object dynamically using dot notation. Thus, myVar will be a property of both the instances and each will have a separate copy of myVar.

Now look at the following example.

Example: this keyword
  
var myVar = 100;

function WhoIsThis() {
    this.myVar = 200;
    
    this.display = function(){
        var myVar = 300;
        
        alert("myVar = " + myVar); // 300
        alert("this.myVar = " + this.myVar);  // 200
    };
}
var obj = new WhoIsThis();

obj.display(); 

In the above example, obj will have two properties myVar and display, where display is a function expression. So, this inside display() method points to obj when calling obj.display().

this behaves the same way when object created using object literal, as shown below.

Example: this keyword

var myVar = 100;

var obj = { 
            myVar : 300, 
	    whoIsThis: function(){
                        var myVar = 200;

                        alert(myVar); // 200
                        alert(this.myVar); // 300
	            }
};

obj.whoIsThis(); 

call and apply:

In JavaScript, a function can be invoked using () operator as well as call() and apply() method as shown below.

Example: Function call
        
function WhoIsThis() {
    alert('Hi');
}

WhoIsThis();
WhoIsThis.call();
WhoIsThis.apply();

In the above example, WhoIsThis(), WhoIsThis.call() and WhoIsThis.apply() executes a function in the same way.

The main purpose of call() and apply() is to set the context of this inside a function irrespective whether that function is being called in the global scope or as object's method.

You can pass an object as a first parameter in call() and apply() to which the this inside a calling function should point to.

The following example demonstrates the call() & apply().

Example: call() & apply()

var myVar = 100;

function WhoIsThis() {

    alert(this.myVar);
}

var obj1 = { myVar : 200 , whoIsThis: WhoIsThis };

var obj2 = { myVar : 300 , whoIsThis: WhoIsThis };

WhoIsThis(); // 'this' will point to window object

WhoIsThis.call(obj1); // 'this' will point to obj1

WhoIsThis.apply(obj2); // 'this' will point to obj2

obj1.whoIsThis.call(window); // 'this' will point to window object

WhoIsThis.apply(obj2); // 'this' will point to obj2

As you can see in the above example, when the function WhoIsThis is called using () operator (like WhoIsThis()) then this inside a function follows the rule- refers to window object. However, when the WhoIsThis is called using call() and apply() method then this refers to an object which is passed as a first parameter irrespective of how the function is being called.

Therefore, this will point to obj1 when a function got called as WhoIsThis.call(obj1). In the same way, this will point to obj2 when a function got called like WhoIsThis.apply(obj2)

bind():

The bind() method was introduced since ECMAScript 5. It can be used to set the context of 'this' to a specified object when a function is invoked.

The bind() method is usually helpful in setting up the context of this for a callback function. Consider the following example.

Example: bind()

var myVar = 100;
    
function SomeFunction(callback)
{
    var myVar = 200;

    callback();
};
      
var obj = {
            myVar: 300,
            WhoIsThis : function() {
                alert("'this' points to " + this + ", myVar = " + this.myVar);
            }
      };
      
SomeFunction(obj.WhoIsThis); 
SomeFunction(obj.WhoIsThis.bind(obj)); 

In the above example, when you pass obj.WhoIsThis as a parameter to the SomeFunction() then this points to global window object insted of obj, because obj.WhoIsThis() will be executed as a global function by JavaScript engine. You can solve this problem by explicitly setting this value using bind() method. Thus, SomeFunction(obj.WhoIsThis.bind(obj)) will set this to obj by specifying obj.WhoIsThis.bind(obj).

Precedence:

So these 4 rules applies to this keyword in order to determine which object this refers to. The following is precedence of order.

  1. bind()
  2. call() and apply()
  3. Object method
  4. Global scope

So, first check whether a function is being called as callback function using bind()? If not then check whether a function is being called using call() or apply() with parmeter? If not then check whether a function is being called as an object function? Otherise check whether a function is being called in the global scope without dot notation or using window object.

Thus, use these simple rules in order to know which object the 'this' refers to inside any function.