The most powerful keyword in JavaScript is this
and many people get tripped by it. People expect it to work like this
in Java, but understand that JavaScript is not Java.
Unfortunately understanding behavior of this
is little harder if you are new to JavaScript, but certainly its not a magic. And as you start getting to used to this
, its rule are actually very simple.
The ‘this’ keyword evaluates to the value of the ‘ThisBinding’ of the current execution context.
The this
value depends on the caller and the type of code being executed and is determined when control enters the execution context. The this
value associated with an execution context is immutable.
And an execution context is a specification device that is used to track the runtime evaluation of code by an ECMAScript implementation. At any point in time, there is at most one execution context that is actually executing code.
So lets understand how this
works in following different contexts-
- Global Context
- Function Context
- Constructor Context
- A DOM Event Handler
1. Global Context
All JavaScript runtimes have a unique object called the global object
. In browsers, the global object is the window
object. When the JavaScript interpreter initially executes code, it first enters into a global execution context by default and this
refers to global object which is window.
1 2 3 4 5 |
|
2. Function Context
Whenever you call a function the execution context changes and the new execution context depends on how you invoked the function.
- If you invoke the function using
Function.call()
orFunction.apply()
,this
will be set to the first argument passed to.call()/.apply()
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Wait, I didn’t use .call()
at line 12 then how the context is window
. Basically whenever you make bare function call i.e. without .call()/.apply()
as above printContext(), JavaScript will convert the call statement to printContext.call(null).
If the first argument passed to .call()/.apply()
is null or undefined, this
will refer to window
. But the catch here is if you are in strict mode
then the value of this
will be whatever its set to while entering into execution context, if not defined it will remain undefined.
- If you create function using
Function.bind()
,this
will be bound the first argument that was passed to.bind()
. In this approach however you make call to the function doesn’t change value ofthis
. CallingprintContext.bind()
creates a new function with same body and scope, butthis
is permanently bound to first argument ofbind
.
1 2 3 4 5 6 7 8 |
|
- If you invoke the function as a method of an object,
this
will refer to that object. But you can still change it to some different object using.call()/.apply()
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
3. Constructor Context
When constructing a new object via new
operator, JavaScript interpreter creates new empty object, set some properties on it and then call the constructor function on that new object. Thus, in this context the value this
is the new object.
1 2 3 4 5 6 |
|
4. A DOM Event Handler
Consider the following example, here the value of this
in the function handler
refers to the button you clicked on. You can observe the same in result tab.
See the Pen this in DOM Event Handler by Shridhar Deshmukh (@shree33) on CodePen.
When you click on the button, the handler
is invoked as method of the button, so this
refers to the target element. How that happens is here, when you say $("button").click(handler)
, there will be a new copy of handler
created and bound to the button using .bind()
. This is done by attachEvent/addEventLister
method.
1 2 3 4 5 6 7 |
|
Summary
That’s it! If you understand and follow above rules, you will always know what this
is.
Context | Non Strict mode | Strict mode |
Global Context | window | window |
.call()/.apply() | First Argument / window | First Argument / undefined |
.bind() | First Argument | First Argument |
function() | window | undefined |
object.function() | object | object |
Constructor Context | New Object | New Object |
DOM Event Handler | The HTML Element | The HTML Element |