Ideally, an application, library, component, or widget defines only a single global variable. That variable should be an object which contains and is the root namespace for all of your stuff. (Douglas Crockford, Global Domination)
JavaScript libraries like YUI, Prototype, and jQuery, all follow a common pattern when it comes to the declaration of the namespace the library is built upon. They prefix the namespace variable with the var keyword, as here:
{[.declaration /enzymes/chili-js.php]}
I think they are wrong, because the var keyword is used for declaring local variables. It usually works fine because the root script (the file which defines the namespace, like yahoo.js) is usually loaded directly into an HTML page, so the local context where it is evaluated is the JavaScript global object.
But if it’s not the case, maybe because I’m using a different method to load the root script, then the library’s namespace could get declared in a local context which is different from the JavaScript global object and it won’t be global as expected by library’s users.
It could be argued that the method used to load the script root is flawed: it should evaluate any loaded script in the global context. But I think that this is a weak argument: a library’s namespace is intended to be global, no matter where the script is evaluated.
Using a platform library for web programming is like buying a superpod for watching tv programs. If I’m on the Earth all goes as expected, but what if I move to the Moon? On the Moon I’d want to turn the superpod on and watch Lost and Prison Break. (No news please, I’m on the Moon.) Anyway I’d get very angry if that super gadget could only tune lunar garbage.
JavaScript doesn’t have a global construct, because it implements implied globals, i.e. any variable defined without the var keyword is considered global. Douglas Crockford doesn’t like implied globals, and JSLint points them out because they could be a mistake, but they are really the only available method to make a variable global.
- Lunar YUI
- works fine if you execute YAHOO = {}; before loading the root script
- Lunar Prototype
- doesn’t work
- Lunar jQuery
- doesn’t work