Douglas Crockford famously said that Javascript is the world’s most misunderstood programming language. How right he was. Javascript is often misunderstood because it’s syntax is very similar to the likes of Java and C++ even though it is a fundamentally different language.

Functions as objects.

Javascript functions are Objects, in other words, Javascript has first-class functions. They can contain properties and other functions. Functions can be assigned to variables. This is fundamentally different to how functions (or methods) work in Java and C++. The idea that functions are objects is key to using the this keyword correcly in Javascript.

What is the this keyword?

MDN says, “Use the this keyword to refer to the current object. In general, this refers to the calling object in a method.”. So it is very similar to the way that this is used in Java or C++ but the thing that makes it different is that functions themselves are objects in Javascript.

An easy example

function f() {
    this.data = "hello world";
    this.getData = function() {
        return this.data;
    };
}

If you remember that a function is an object then this example is pretty straightforward. A function f() is created, it has a property called data and a method (another name for a function inside an object) called getData. You can use f() like this:

var a = new f();
alert( a.getData() );
alert( a.data );

We are creating a new instance of function f() and assigning it to a variable called a, we can then call the getData() method on our new object called a or we can use its data property. That’s all good.

When things go bad.

The surprising thing about this that catches out most people when they start using Javascript is that it changes when a function is called from a different object. Remember that this refers to the current object. To illustrate how the the value of this can change we can do this:

var b = a.getData;

Variable b is now a reference to the getData function. We can execute it by doing this:

b();

But this will not work because this.data is no longer “hello world”, it is undefined and the reason this is so is because when we called a.getData() above the function was a method of function f() and this referred to f() but b() is no longer a method of f() and this points to something completely different.

What does this point to now?

Because we didn’t declare our b variable inside an object it is in the global scope and, assuming you are running Javascript in a browser, the global scope is the Window object, so this.data is now really window.data and that property is not defined in that object.

Try it for yourself.

Run and edit the above example in these jFiddles (just click run from the top menu):

http://jsfiddle.net/wh3Qf/ – The simple example that works.

http://jsfiddle.net/wh3Qf/1/ – Calling the getData() function from somewhere else and changing the scope of this.

http://jsfiddle.net/wh3Qf/2/ – Question time: What will the last alert() call print if you un-comment it, and why?

We can fix this.

There’s a few different ways of avoiding problems with this, I’ve covered them here.