Thursday, September 14th, 2006

JavaScript Closures for Dummies

Category: Articles, Examples, JavaScript

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.

Posted by Dion Almaer at 8:46 am
7 Comments

++++-
4.1 rating from 32 votes

7 Comments »

Comments feed TrackBack URI

Excellent.

Comment by Vance Dubberly — September 14, 2006

“(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);
}

Comment by Ruairi — September 14, 2006

Interesting Finds: September 14, 2006

Trackback by Jason Haley — September 14, 2006

@ Ruairi do you have any more clear cut usefull examples of what you describe?

Comment by Mario — September 15, 2006

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.

Comment by Ruairi — September 15, 2006

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);
}

Comment by henrah — September 16, 2006

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).

Comment by Ruairi — October 9, 2006

Leave a comment

You must be logged in to post a comment.