I’m really not a JS ninja, but as the defacto language of the Web, it’s rather a unique day if i don’t read or write some javascript code and this a pattern that is well worth to know.
First example, a simple var:
function myFunction() {
var myVar = 'test';
setTimeout('alert(myVar)', 1000);
};
myFunction();
fails with myVar is not defined error, because setTimout works on the window object (the top level object for browsers), and there is no myVar registered as a global var (window.myVar is undefined).
You can easily work this out with a closure:
function myFunction() {
var myVar = 'test';
setTimeout(function() { alert(myVar) }, 1000);
};
myFunction();
simply a closure is a function declared inside other function. We have an anonymous function as the first argument of setTimeout inside myFunction, so it’s a closure. The magic of closures is that they keep state (the local variables remain accessible) after the container function has exited.
The curious case of this keyword… take the code:
function myClass () {
this.myVar = 'test';
this.myFunction = function() {
setTimeout(function() {alert(this.myVar)}, 1000);
}
}
myobj = new myClass();
myobj.myFunction();
and boum! undefined pops-up, WTF? after messing around with call, apply and even with i could only make it work assigning this to a local variable:
function myClass () {
var self = this;
this.myVar = 'test';
this.myFunction = function() {
setTimeout(function() {alert(self.myVar)}, 1000);
}
}
myobj = new myClass();
myobj.myFunction();
this of course is a non elegant solution, so please be my guest of posting a better solution to this issue.