(In Portugese)

The JavaScript this keyword is ubiquitous yet misconceptions abound.

What you need to know

Every execution context has an associated ThisBinding whose lifespan is equal to that of the execution context and whose value is constant. There are three types of execution context: global, function and evaluation. Here’s a tabular summary followed by a little more detail, and some examples:

Execution Context Syntax of function call Value of this Global n/a global object (e.g. window ) Function Method call:

myObject.foo(); myObject Function Baseless function call:

foo(); global object (e.g. window )

( undefined in strict mode) Function Using call:

foo.call(context, myArg); context Function Using apply:

foo.apply(context, [myArgs]); context Function Constructor with new:

var newFoo = new Foo(); the new instance

(e.g. newFoo )

Evaluation n/a value of this in parent context

1. Global context

this is bound to the global object ( window in a browser)

alert(this); //window



2. Function context

There are at least 5 ways to invoke a function. The value of this depends on the method of invocation

a) Invoke as a method

this is the baseValue of the property reference

var a = { b: function() { return this; } }; a.b(); //a; a['b'](); //a; var c= {}; c.d = a.b; c.d(); //c

b) Invoke as baseless function call

this is the global object (or undefined in strict mode)

var a = { b: function() { return this; } }; var foo = a.b; foo(); //window var a = { b: function() { var c = function() { return this; }; return c(); } }; a.b(); //window

The same applies to self invoking functions:

var a = { b: function() { return (function() {return this;})(); } }; a.b(); //window

c) Invoke using Function.prototype.call

this is passed by argument

d) Invoke using Function.prototype.apply

this is passed by argument

var a = { b: function() { return this; } }; var d = {}; a.b.apply(d); //d

e) Invoke a constructor using new

this is the newly created object

var A = function() { this.toString = function(){return "I'm an A"}; }; new A(); //"I'm an A"



3. Evaluation context

this value is taken from the this value of the calling execution context

alert(eval('this==window')); //true - (except firebug, see above) var a = { b: function() { eval('alert(this==a)'); } }; a.b(); //true;

What you might want to know

This section explores the process by which this gets its value in the functional context – using ECMA-262 version 5.1 as a reference.

Lets start with the ECMAScript definition of this :

The this keyword evaluates to the value of the ThisBinding of the current execution context.

from ECMA 5.1, 11.1.1

How is ThisBinding set?

Each function defines a [[Call]] internal method (ECMA 5.1, 13.2.1 [[Call]]) which passes invocation values to the function’s execution context:

The following steps are performed when control enters the execution context for function code contained in function object F, a caller provided thisValue, and a caller provided argumentsList:

1. If the function code is strict code, set the ThisBinding to thisValue.

2. Else if thisValue is null or undefined, set the ThisBinding to the global object.

3. Else if Type(thisValue) is not Object, set the ThisBinding to ToObject(thisValue).

4. Else set the ThisBinding to thisValue

from ECMA 5.1, 10.4.3 Entering Function Code (slightly edited)

In other words ThisBinding is set to the object coercion of the abstract argument thisValue , or if thisValue is undefined, the global object (unless running in strict mode in which case thisValue is assigned to ThisBinding as-is)

So where does thisValue come from?

Here we need to go back to our 5 types of function invocation:

1. Invoke as a method

2. Invoke as baseless function call

in ECMAScript parlance these are Function Calls and have two components: a MemberExpression and an Arguments list.

1. Let ref be the result of evaluating MemberExpression.

2. Let func be GetValue(ref).

6. If Type(ref) is Reference, then

a. If IsPropertyReference(ref) is true

i. Let thisValue be GetBase(ref).

b. Else, the base of ref is an Environment Record

i. Let thisValue be the result of calling the ImplicitThisValue concrete method of GetBase(ref).

8. Return the result of calling the [[Call]] internal method on func, providing thisValue as the this value and

providing the list argList as the argument values

from ECMA 5.1, 11.2.3 Function Calls

So, in essence, thisValue becomes the baseValue of the function expression (see step 6, above).

In a method call the function is expressed as a property, so the baseValue is the identifier preceding the dot (or square bracket).

foo.bar(); // foo assigned to thisValue

foo[‘bar’](); // foo assigned to thisValue

var foo = { bar:function() { //(Comments apply to example invocation only) //MemberExpression = foo.bar //thisValue = foo //ThisBinding = foo return this; } }; foo.bar(); //foo

A baseless function is either a function declaration or a variable – in either case the baseValue is the Environment Record (specifically a Declarative Environment Record). ES 5.1, 10.2.1.1.6 tells us that the ImplcitThisValue of a Declarative Environment Record is undefined.

Revisiting 10.4.3 Entering Function Code (see above) we see that unless in strict mode, an undefined thisValue results in a ThisBinding value of global object. So this in a baseless function invocation will be the global object. In strict mode the ThisBinding remains undefined.

In full…

var bar = function() { //(Comments apply to example invocation only) //MemberExpression = bar //thisValue = undefined //ThisBinding = global object (e.g. window) return this }; bar(); //window

3. Invoke using Function.prototype.apply

4. Invoke using Function.prototype.call

(specifications at 15.3.4.3 Function.prototype.apply and 15.3.4.4 Function.prototype.call)

These sections describe how, in call and apply invocations, the actual value of the function’s this argument (i.e. its first argument) is passed as the thisValue to 10.4.3 Entering Function Code. (Note this differs from ECMA 3 where primitive thisArg values undergo a toObject transformation, and null or undefined values are converted to the global object – but the difference will normally be negligible since the value will undergo identical transformations in the target function invocation (as we’ve already seen in 10.4.3 Entering Function Code))

5. Invoke a constructor using new

When the [[Construct]] internal method for a Function object F is called with a possibly empty list of arguments, the following steps are taken:

1. Let obj be a newly created native ECMAScript object.

8. Let result be the result of calling the [[Call]] internal property of F, providing obj as the thisValue and providing the argument list passed into [[Construct]] as args.

10. Return obj.

from ECMA 5.1, 13.2.2 [[Construct]]

This is pretty clear. Invoking the constructor with new creates an object that gets assigned as the thisValue. It’s also a radical departure from any other usage of this .

House Cleaning

Strict mode

In ECMAScript’s strict mode, the thisValue is not coerced to an object. A

this value of null or undefined is not converted to the global object and primitive values are not converted to wrapper objects

The bind function

Function.prototype.bind is new in ECMAScript 5 but will already be familiar to users of major frameworks. Based on call/apply it allows you to prebake the thisValue of an execution context using simple syntax. This is especially useful for event handling code, for example a function to be invoked by a button click, where the ThisBinding of the handler will default to the baseValue of the property being invoked – i.e. the button element:

//Bad Example: fails because ThisBinding of handler will be button var sorter = { sort: function() { alert('sorting'); }, requestSorting: function() { this.sort(); } } $('sortButton').onclick = sorter.requestSorting;

//Good Example: sorter baked into ThisBinding of handler var sorter = { sort: function() { alert('sorting'); }, requestSorting: function() { this.sort(); } } $('sortButton').onclick = sorter.requestSorting.bind(sorter);

Further Reading

ECMA 262, Edition 5.1

11.1.1 Definition of this

10.4.3 Entering Function Code

11.2.3 Function Calls

13.2.1 [[Call]]

10.2.1.1 Declarative Environment Record (ImplicitThisValue)

11.1.1 [[Construct]]

15.3.4.3 Function.prototype.apply

15.3.4.4 Function.prototype.call

15.3.4.5 Function.prototype.bind

Annex C The Strict Mode of ECMAScript