One of the things that tripped me up when I first learned JavaScript was the “this” keyword. I came from a pure OO world, where classes were clearly defined objects, and “this” always referred to the object in context. JavaScript is a prototype based scripting language, though, and as such, doesn’t have the concept of a class. The “this” keyword means something very different in JavaScript.

According to the ECMAScript language specification:

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

And the “ThisBinding” keyword is:

The value associated with the this keyword within ECMAScript code associated with this execution context.

So, both definitions refer to the other, which I was always taught in elementary school was not to be done! In my opinion, this definition is rather useless to the new JavaScript developer. Practical examples are much more useful!

In JavaScript in a browser, all global functions are bound to the Window object. You can see the behavior by running this bit of code in any browser’s developer console:

(function () {
    console.log(this); // [object Window]
})();

It’s a self executing function that exists in the global scope, and the console.log(this); line should write out [object Window] or something similar. That’s because “this” is a reference to Window. In a function like this, anything that exists on the Window object is also available through the “this” keyword:

(function () {
    this.alert(0);
})();

Because the alert function exists in the global scope, it is attached to the Window object. A related phenomenon occurs when you declare global variables:

hello = function() {
    alert('hello');
}

(function () {
    this.hello(); // same as calling window.alert('hello');
})();

This is the default behavior, but that’s only when functions are declared, or rather, bound to the global scope when executed. One can easily rebind a function with .call() or .apply():

var newobj = {
    alertit: function (message) {
        alert(message);
    }
};

var func = function (message1, message2) {
    this.alertit(message1 + " " + message2);
};

func.call(newobj, 'hello', 'world'); // alerts hello world
func.apply(newobj, ['hello', 'world']); // alerts hello world

the .call() and .apply() functions are both used to change the “this” keyword binding, or the “ThisBinding” as described in the ECMAScript spec. They do the exact same thing, but they pass parameters into the called function differently. The .call() function takes a dynamic parameter set, and the .apply() function takes an array of parameters. Either way, you can see that ‘func’ is called the same way, with its “this” keyword bound to the newobj object.

In the case where a function is already scoped to an object, the “this” keyword will reference the parent object:

var NewObj = function () {};

NewObj.prototype.alert = function (message) {
    alert('NewObj alert: ' + message);
};

NewObj.prototype.test = function (message) {
    this.alert(message);
};

var newobj = new NewObj();
newobj.test('test'); // alerts NewObj alert: test
newobj.test.call(window, 'test'); // alerts test

In this case, the first newobj.test() is called while using the default binding, which is the instance of NewObj that was created, so when it calls this.alert(), it is calling the object’s prototype.alert() function.

The second time it is called, I forced a rebind to the window object, by using .call(). This causes the normal global alert() function to be the one called, since in this call, “this” is bound to window.

I hope this clears up a common problem for someone. I certainly had a hard time understanding “this” when I first learned JavaScript, but hopefully it makes more sense after seeing a few examples.

One thought on “JavaScript and the “this” keyword

  1. Pingback: How does JavaScript Scope work? | Geek Powers

Leave a Reply

Your email address will not be published. Required fields are marked *