Something Like “this”

Few people learn JavaScript as a first programming language. Typically people will start with an object-oriented language such as C#, Java or C++. These languages have a few things in common, such as curly braces, objects, functions, if-statements and loops. Another common feature of object-oriented programming languages is the ‘this’ keyword. It refers to the class which contains the currently executing code.

It can be something of a surprise then when a programmer moves on to JavaScript and discovers that the value returned by ‘this’ is less predictable than expected.

There are five different cases where you might use ‘this’. These include using it in the global namespace, and four different ways of using it inside a function, as described by Douglas Crockford in JavaScript – The Good Parts.

‘this’ in the Global Namespace

In the global namespace, that is, outside of any function, ‘this’ refers to the window object. I don’t see any reason why anyone would want to use ‘this’ in the global namespace, in fact it’s probably a bad idea, nevertheless it can be done and so is worth mentioning for completeness.

Scenario 1 – Method Invocation

In JavaScript (and many other languages) a method is a function which is declared inside of a class or object. Referring to ‘this’ inside of a method refers to the containing object. Therefore in the example below we are alerted with ‘Roberto Martinez’ rather than ‘Howard Kendall’.

This is the kind of behaviour you would expect coming from an object-oriented background, so no unpleasant surprises here.

Scenario 2 – Function Invocation

Here we are referring to any function which is not declared inside an object. That is, any function which is declared in the global namespace. Using ‘this’ inside such functions actually refers to the global namespace, rather than the containing function. Strange behaviour indeed, and Douglas Crockford actually describes this behaviour as a mistake by the creators of JavaScript. Thus in the example below, we are alerted with ‘Howard Kendall’, rather than ‘Roberto Martinez’.

So we have established that ‘this’ inside of a method refers to the method’s containing object, and ‘this’ inside of a global function refers to the global namespace. But what is referred to by ‘this’ inside of a function which is declared inside of a method? The answer is – the global namespace, as shown in the example below.

This behaviour is slightly surprising. If we want to use an inner function inside of a method, we can get around the problem by assigning ‘this’ to a variable inside the outer method, as shown below with the ‘that’ variable.

Scenario 3 – Constructor Invocation

A third function scenario is that of the constructor function, that is, a function which is invoked with the ‘new’ keyword. When a function is invoked in this way, the ‘this’ keyword refers to the object created, even if the constructor function was defined in the global namespace. Therefore, in the example below we are alerted first with ‘Howard Kendall’ and then with ‘Joe Royle’. We refer to ‘this’ inside of a global namespace function when we set the ‘manager’ variable inside of ‘getEverton’, but as we call the function with the ‘new’ keyword, the global namespace ‘manager’ variable is not updated.

The same behaviour is displayed when we call a method declared on the constructor function’s prototype, and properties can be set on our new object in the normal way.

So to summarise constructor invocation, it reflects typical object-oriented behaviour more closely that function invocation. However, it can be dangerous to rely on this approach, as if we forget to use the ‘new’ keyword, our constructor function will be invoked as a regular global function, and we will see the behaviour described above in scenario 2.

Scenario 4 – Apply Invocation

Our final function invocation scenario is the apply invocation pattern. The apply method is defined on the function prototype, therefore it can be invoked on any function. This approach to invocation allows us to provide any object we want to represent ‘this’ inside of the function. Its first argument is bound to ‘this’, and its second argument is an optional array of parameters to be passed to the function. Thus in the example below, we are first alerted with ‘Joe Royle’ and then with ‘Harry Catterick’.

I have attempted here to clearly describe the different behaviours you might see when using the ‘this’ keyword in JavaScript. However, it is a difficult area to describe in plain english. If you find my descriptions confusing I recommend reading Crockford’s book. All the code examples are available to play with at this jsfiddle.

Share Button
  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1672()

  • Yaroslav Yakovlev

    For some reason it doesnt work in jsfiddle:
    It seems variable assignment are not adding properties to window. Same thing works fine in js console and in, say Any ideas why it is like so?

    • Ronnie Mukherjee

      Hi Yaroslav,

      Yes, for some reason in jsfiddle you need to explicitly use ‘this’ to add a variable to the global namespace. As you correctly say you wouldn’t normally have to do this.