With reference to our previous example, this would give us:
setTimeout(greet, 1000, randomGreeting);
Unfortunately, this doesn’t work in IE9 or below, where the parameters come through as undefined. There is however, a pollyfill available on MDN.
The Problem With this
Code executed by setTimeout is run in a separate execution context to the function from which it was called. This is problematic when the context of the this keyword is important:
var person = { firstName: "Jim", introduce: function(){ console.log("Hi, I'm " + this.firstName); } }; person.introduce(); // Outputs: Hi, I'm Jim setTimeout(person.introduce, 50); // Outputs: Hi, I'm undefined
The reason for this output is that in the first example, this points to the person object, whilst in the second example this points to the global window object (which doesn’t have a firstName property).
To counteract this, there are various measures:
Explicitly set the value of this
You can do this using bind, a method which creates a new function that, when called, has its this keyword set to the provided value (in our case the person object). This would give us:
setTimeout(person.introduce.bind(person), 50);
Note: bind was introduced in ECMAScript 5, so will only work in more modern browsers. You can read more about it (and other methods of setting the value of this) in this SitePoint article.
Use a Library
Many libraries come with built in functions to address this issue. For example, jQuery’s jQuery.proxy() method. This takes a function and returns a new one that will always have a particular context. In our case, that would be: