The value of
this inside a function, effectively depends on the object which called it. The ECMAScript Language Specification says, “The this keyword evaluates to the value of the ThisBinding of the current execution context.”
The use of the “this” keyword inside a function should be familiar to the C++/C# developers among us—it refers to the object through which the method is called ( developers who use Visual Basic should find it familiar, too—it’s called “Me” in Visual Basic).
The Value of this Depends on Context
We talked about scope in a previous posting in this series. Scope is when a variable name or other identifier is valid and can be used. Outside the scope of a variable name, the variable’s value may still be stored, and is not accessible in some way.
So what does that mean to the this keyword?
The ECMAScript Standard defines
<script> element is encountered:
When evaluating code in the initial global execution context, ThisBinding is set to the global object,
Entering eval code
The ThisBinding is updated
… by a direct call to eval()
ThisBinding is left unchanged; it is the same value as the ThisBinding of the calling execution context.
… if not by a direct call to eval()
ThisBinding is set to the global object as if executing in the initial global execution context.
§188.8.131.52.1 defines what a direct call to eval() is. Basically,
eval(...) is a direct call whereas something like
(0, eval)(...) or
Inside a Function
this. always refers to the “owner” of the function we’re executing, or rather, to the object that a function is a method of.
In the function makeMeRed(), the owner is the page so this returns the window object.
If a function is called on an object, such as in
obj.myMethod() or the equivalent
obj["myMethod"](), then ThisBinding is set to the object. In most other cases, ThisBinding is set to the global object
The reason for writing “in most other cases” is because there are eight ECMAScript 5 built-in functions that allow ThisBinding to be specified in the arguments list. These special functions take a so-called thisArg which becomes the ThisBinding when calling the function.
These special built-in functions are:
- Function.prototype.apply( thisArg, argArray )
- Function.prototype.call( thisArg [ , arg1 [ , arg2, … ] ] )
- Function.prototype.bind( thisArg [ , arg1 [ , arg2, … ] ] )
- Array.prototype.every( callbackfn [ , thisArg ] )
- Array.prototype.some( callbackfn [ , thisArg ] )
- Array.prototype.forEach( callbackfn [ , thisArg ] )
- Array.prototype.map( callbackfn [ , thisArg ] )
- Array.prototype.filter( callbackfn [ , thisArg ] )
In the case of the Function.prototype functions, they are called on a function object, but rather than setting ThisBinding to the function object, ThisBinding is set to the thisArg.
In the case of the Array.prototype functions, the given callbackfn is called in an execution context where ThisBinding is set to thisArg if supplied; otherwise, to the global object.
Using the ‘new’ operator
When constructing a new object via the
this is the new object that the interpreter created:
this to library functions, you should refer to the documentation for any guarantees about what the value of
this is when the function is called.
To summarize, every function object has a method named call, which calls the function as a method of the first argument. That is, whichever object we pass into call as its first argument will become the value of “this” in the function invocation.
Here’s an example of using this and showing how it changes as the object changes.
The output is
It is a wise father that knows his own child. Golf is a good walk spoiled. True friends stab you in the front.
You can try it here: http://jsfiddle.net/w0ve2r04/1/
Inside an Event
Inside an event, the owner is the HTML element the event belongs to. For example, in an onclick event, the owner is the element that fired the event.
In an event handler for an element, with default capturing (false),
this will refer to the element which detected the event.
When capturing an event (true), say at the window level,
event.target, will refer to the element which originated the event, while
this will refer to the capturing element. For example:
Call and Apply and Bind
You can use
bind()when you want that function to later be called with a certain context.
apply() to call the function immediately, or use
bind()to return a function that when later executed will have the correct context set for calling the original function. This way you can maintain context in async callbacks, and events.
is the equilivant of:
Function.prototype inherits this
Where a function uses the
this keyword in its body, its value can be bound to a particular object during execution using the
apply() methods that all functions inherit from Function.prototype.
When you want async callbacks and pass a member method for, but still want the context to be the instance that started the async action, you can use a simple naïve implementation of bind:
Take the Quiz