Vincenzo Alcamo wrote to me with another practical use for closures in JavaScript. Vincenzo is working on a JavaScript library he calls XMLLib, based on the Sarissa library. To prevent his library from cluttering the global namespace, Vinceno defines his symbols in his own XMLLib namespace, of course.
But he goes one step further. In Vincenzo's code, only publically exported methods and properties ever get stored in the XMLLib object. Internal, helper methods that are not intended for public use exist in a closure, where all the public methods can use them but where they are hidden from everyone else.
Schematically, the code looks like this:
// Create an empty namespace
XMLLIB = {}
(function() { // anonymous function creates a closure for us
// Thi s is a private method that stays hidden within the closure
function private_utilty_method() { /* utility code here */ }
// This method is exported into the XMLLib namespace, so it is a public method
// But since it is defined here, it can call private methods like the one above.
XMLLib.publicMethod = function() { /* ... */}
})(); // Close function definition and invoke it all at once
Contrast this approach to private symbols with that taken by JSAN. In that framework, a namespace may contain a mix of public and private symbols. The namespace also declares an array of symbols that should be exported by default, and an array of symbol that are allowed to be exported from the namespace. Any symbols excluded from these arrays are private, and the JSAN exporter functions will not copy them into the global namespace. That is, the JSAN framework does not have true privacy via closures, but defines a convention which, when followed, provides a measure of privacy.
Thanks for the tip, Vincenzo!




The major benefit of using function scope is that you don't have to refer to internal symbols with their fully qualified names. Hiding private methods from users of your code just makes life harder for everyone, so I wouldn't say that it's a useful feature. The cons are that users can't re-implement any piece of your library (i.e. inject a bugfixed version of a function) because the actual functions will still be seen in the closed over function scope, and this method makes debugging just that much more difficult, especially under crappy JavaScript implementations.
I had originally used this approach when I was refactoring MochiKit for namespaces, but I found that it was damn near impossible to track down some JScript implementation bugs this way, so I decided on the "no magic" approach that you see in most other namespace-using libraries. Using the "no magic" approach didn't fix the JScript bug, but it allowed me to find it.
I do use the function scope trick a little bit, by defining a __new__ method on the namespace, which allows me to populate it using "this.foo = bar". I mostly do that because there is a chunk of generic setup code in each MochiKit module and it makes cut and paste easy (since it can just use "this"). I also typically put all code that doesn't simply define a function or constant in there for organizational purposes (e.g. defining an adapter registry, setting up convenience aliases, creating exceptions, etc.).
By the way, this is TOTALLY orthogonal to JSAN. JSAN says you should use namespaces, it doesn't say whether you should or shouldn't use a function scope trick to populate the namespace. The reason that you don't see many people using this trick is probably the same reason I'm no longer using it.
Yeah, I was just going to say the same: the JSAN convention only defines a convention that applies to public methods. The treatment of private ones is entirely up to you.