The this keyword (JavaScript)
An overview of how the this keyword works in JavaScript
Basic idea
- Every function has access to a
this
reference - The
this
reference is assigned a value when creating the execution context for an execution of the function (see Scope and closures)- Note that this means that a function's
this
can point to different things based on how it's executed! - Run-time binding, not write-time binding! In that sense, it's a bit the opposite of lexical scoping (see Scope and closures)
- Note that this means that a function's
- What the
this
reference points to is determined by a number of rules
this
Rules for binding Default binding
This is the most basic case, where the function is directly called without doing anything special with it
Example:
What this
is bound to depends on strict mode:
- If strict mode is not enabled, the function's
this
points to the global object. Since the global object has a variablea
with valuetest
, the code will printtest
- If strict mode is enabled, the function's
this
is not allowed to point to the global object. Instead,this
points toundefined
, and the code throws aTypeError
because we tried to accessundefined.a
Implicit binding
Implicit binding occurs when the function is called through an object that holds a reference to it. In this case, that object is called the context object and the function's this
points to the object.
Example:
One tricky thing: it's easy to lose that implicit binding!
As we see above, assigning the function to a variable and then calling it doesn't use implicit binding anymore. Instead, we fall back to default binding.
One case where we need to be careful with that is when passing functions around as callbacks. Example:
Explicit binding
As the name suggests, explicit binding is more explicit about what the function's this
reference is bound to
Example:
Some things to notice:
call
andapply
can be used to call a function while explicitly specifying whatthis
should point to. You can use these to dynamically call a function with anythis
reference you like.bind
returns a new function that is identical the original function except that itsthis
is hard-wired to the argument you passed tobind
. One use case is passing the function as a callback (see example code above)
Other use case: monkey patching (extending the behavior of a function defined on an existing object):
new
binding
The new
binding occurs when using the keyword new
to call a function. Invoking a function using the new
keyword has the following effect:
- A new object is created
- The new object's
__proto__
points to the function (see Object prototypes and classes) - The new object is set as the
this
binding for that call to the function - Unless the function returns something itself, the function call will automatically return the new object
Important: new
does not require any specific kind of function to be called on! It can be used on any function, and when it does, it modifies the function's behavior according to the above. In this case, the function is sometimes called a constructor, but it is still just a regular function. The only thing making it behave differently is the new
keyword.
Example:
Priority of the rules
From highest to lowest:
new
binding (overrides all the rest)- Explicit binding
- Implicit binding
- Default binding
this
Lexical One exception to the behavior of this
inside a function occurs when using arrow functions. Arrow function's don't follow the rules above. Instead, the this
inside an arrow function points to the this
of the surrounding scope.
One use case: calling other function on same object from a callback
Also note that, because of the fact that arrow functions don't have their own this
, JavaScript does not allow you to call them using the new
keyword: