Functions and this

Understanding this in JavaScript is hard, but also vital. It corresponds, roughly, to the use of self in Python. But there are big differences. We start with the pitfalls, then give the valuable use, and then give another pitfall.

We need this to do efficient object oriented programming in JavaScript. But there are potential pitfalls, which we describe first. We then describe the useful applications of this.

Note

It’s not possible to get far in JavaScript without understanding this. But understanding this is helps you become a confident expert. Please persevere until you get it.

Pitfalls

Here we describe some of the traps that await the unwary.

this is a keyword

Unlike Python’s self, in JavaScript this is a keyword. It is not possible to explicitly assign a value to this.

js> this = 1
typein:2: SyntaxError: invalid assignment left-hand side:
typein:2: this = 1
typein:2: .....^

We have here a syntax error. As in Python, each identifier in JavaScript, potentially, refers to an object. We can make the identifier refer to a different object by writing:

a = new_value;               // Sometimes called 'rebinding'.

But this is not an identifier. It is a keyword, and

this = new_value;

is a syntax error. Good editors highlight this to point out its special role.

Mutating this

Even though we cannot assign to this, we can mutate the this-object. It is best to think of this as quasi-fixed but mutable object. (There are ways of changing what this refers to, but not in the body of an executing function.)

js> a = this;
js> a.name = 'gotcha'        // Mutating the *this* object.
js> b = this;
js> a === b && a === this    // a, b and *this* are the same object.
true
js> this.name                // We have mutated *this*.
gotcha

The keyword this is bound to the same object as before, but that object has been mutated. (There are two ways to ‘change <identifier>’, namely rebinding and mutation. But rebinding of this is not allowed.)

Global this gotcha

JavaScript has a global object, which roughly corresponds to the __main__ module in Python. However, unlike __main__, we should try to avoid using and changing JavaScript’s global object. [link]

Let’s continue the previous example. We just mutated the this object, by adding a name to it. But what object did we change? In fact, we’ve just added a new global value.

js> name
gotcha

Even if you don’t understand why this happened (and it’s not been explained yet [link]), it is something that quality code must avoid.

Note

Whenever you mutate this, be sure you know what object this is.

Methods and this

There are two ways to set this, namely implicit and explict. Here we describe the implicit method. The rule is quite simple.

Suppose we execute

result = obj.method()

where obj.method is a function. (If obj.method is not a function we get a runtime error.)

In this situation, this is bound to obj during this execution of method. Here is an example:

js> var obj = {}
js> obj.name = 'apple'
apple
js> obj.method = function(){return this.name}
js> obj.method()
apple

Here’s a similar example, involving inheritance:

js> parent = {}
js> parent.method = function(){return this.name}
js> a = create(parent)
js> a.name = 'apple'
apple
js> a.method()
apple

Explicit this

For a summary, see the earlier section Calling a function. For the details, see [link] and for examples see [link].