Closures in JavaScript are a very important tool. The ability to control the execution contexts of variables and functions gives a lot of power. In some cases, closures aren’t only handy and powerful, they are necessary. For example, in the process of wrapping up a JavaScript AutoSave, I ran into a bit of a scoping problem with setTimeout().
As you know, setTimeout hangs off of the ‘window’ scope. The fully qualified call is window.setTimeout(). Inside of my javascript object I created a setTimeout command to run the doSave() function. The setTimeout() function takes two arguments:
- The Code to execute on completion
- The number of milliseconds before executing Arg1
Since I was several layers inside the AutoSave object, I addressed the function as this.doSave(). The problem arose that the execution context of setTimeout means that ‘this’ will not resolve into my handy doSave function. I could have addressed the function by the global variable containing my AutoSave object, but that would reduce the reusability of my JavaScript object.
What I needed was a way to maintain the variables from one scope into another scope and that is where the closure came in.
startTimer : function(){
if (! _timerRunning){
var _OnTimeoutEnd = this.doSave;
_timer = setTimeout ( function(){ _OnTimeoutEnd()}, _SaveCycleLength );
_timerRunning = true;
}
},
This piece is specifically the closure.
function(){ _OnTimeoutEnd()}
Notice above how I get a reference to the function doSave from the this scope. Inside the AutoSave object, ‘this’ points to the AutoSave object. Then I set this.doSave to a new variable which I then put inside the first argument of setTimeout.
When this code executes, _OnTimeoutEnd correctly resolves to the AutoSave.doSave function and the save is completed.
JavaScript closures are very powerful and should become a part of your toolbox as well. If you would like to read more about Closures in JavaScript, I suggest Javascript Closures
by Richard Cornford.