Thursday, September 14th, 2006
JavaScript Closures for Dummies
<>p>Morris Johns has gone though and written a detailed explanation of closures by example:If everything seems completely unclear then the best thing to do is to play with t e examples. Reading an explanation is much harder than understanding example
My explanations of closures and stack-frames etc are not technically correct – they are gross simplifications intended to help understanding. Once the basic idea is grokked, you can pick up the details later.Final points:
- Whenever you use function inside another function, a closure is used.
- Whenever you use eval() inside a function, a closure is used. The text you eval can reference local variables of the function, and within eval you can even create new local variables by using eval(‘var foo = …
- When you use Function() inside a function, it does not create a closure. (The new function cannot reference the local variables of the function calling Function()).
- A closure in JavaScript is like keeping a copy of the all the local variables, just as they were when a function exited.
- It is probably best to think that a closure is always created just on entry to a function, and the local variables are added to that closure.
- A new set of local variables is kept every time a function with a closure is called (Given that the function contains a function declaration inside it, and a reference to that inside function is either returned or an external reference is kept for it in some way).
- Two functions might look like they have the same source text, but have completely different behaviour because of their ‘hidden’ closure. I don’t think JavaScript code can actually find out if a function reference has a closure or not.
- If you are trying to do any dynamic source code modifications ( for example: myFunction = Function(myFunction.toString().replace(/Hello/,’Hola’)); ), it won’t work if myFunction is a closure (Of course, you would never even think of doing source code string substitution at runtime, but…).
- It is possible to get function declarations within function declarations within functions – and you can get closures at more than one level.
- I think normally a closure is the term for both the function along with the variables that are captured. Note that I do not use that definition in this article!
- I suspect that closures in JavaScript differ from those normally found in functional languages.
Related Content:











Excellent.
“(Of course, you would never even think of doing source code string substitution at runtime, but…)”
// hears voices saying: “hee hee hee…”
Of course I would, here’s a snippet from the history bin:
DataSet.prototype.sort = function (strategy, column) {
var sortsrc = strategy.toString();
var func = sortsrc.substring(sortsrc.indexOf("{")+1, sortsrc.lastIndexOf("}"));
func = func.replace(/a/, "a['" + column + "']").replace(/b/, "b['" + column + "']");
strategy = new Function("a","b",func);
this.rows = this.rows.sort(strategy);
}
Interesting Finds: September 14, 2006
@ Ruairi do you have any more clear cut usefull examples of what you describe?
Mario,
this is code for sorting a DataSet (source code). This allows me to sort the rows of a DataSet, specifying a column and a sort function (using the native Array.prototype.sort method). A table could use the dataset as the model and the data would be easily sortable on any column and any way you’d like to sort the data.
but Ruari, wouldn’t you rather use a closure and avoid recompilation / potential syntax errors?
DataSet.prototype.sort = function (strategy, column) {var innerStrategy = function(a, b){
return strategy(a[column], b[column])
};
this.rows = this.rows.sort(innerStrategy);
}
henrah,
In this day and age I would. When I wrote that code, I was still young and reckless (was about 5 years ago and I did not really have my closures down).