We’re always told that globals are evil and that we should never use global variables. While it certainly is true that globals offer a considerable performance hit, it is nearly impossible to avoid global variables.
There are two basic types of applications a programmer can write in JavaScript: simple ones and not so simple ones. Think of simple applications as the 5 or 10 liners that generally wind up a the bottom of a page (yes, we all know JavaScript should be external but everyone breaks this rule from time-to-time). Likewise, not so simple apps are everything else.
Avoiding Globals Entirely
If you find yourself writing simple apps frequently, you can generally get away without creating any additional globals by wrapping your application in a self-invoking function:
(function () {
var popupCallback = function (event) {
window.open(this.href);
};
var anchors = document.getElementsByTagName('a');
var length = anchors.length;
for (var i = 0; i < length; i++) {
var a = anchors[i];
if (a.getAttribute('rel') === 'external') {
a.addEventHandler('click', popupCallback, false);
}
}
})();
Of course, the moment you need to do anything more complicated than this, you’ll probably need to create a global variable to link libraries against.
When You Can’t Avoid Globals
In the cases (which are more often than not) where you can’t avoid creating global variables, it’s best to set some rules up so that you can avoid going crazy.
First off, forget the notion that you will have only one global variable. The moment you start introducing libraries into your application, you’ll be adding global variables.
I recommend using the following rules:
- Namespace everything
- One global name is allowed per library or framework (jQuery, YUI, etc)
- One global name is allowed per application (contactForm, shoppingBasket, searchBar)
Namespaces
I’ve written about JavaScript namespaces in the past be sure to read up on that. These should be common practice by now, but there’s still some best practices which need to be discussed with regards to responsible namespace creation. Hang tight, I’ll be discussing these in depth in my next post.
Libraries and Frameworks
Lets hope you’re using a modern framework like jQuery or YUI which actually respects the global object and does its best to not pollute it. With this in mind I allow one global object per library.
So for example, if I include jQuery, that creates the window.jQuery object (lets assume I have compatibility mode set, so it doesn’t create the $ object — which I will also be talking about later too).
I also may want to include my own home-grown framework to make use of some utilities I wrote. This makes two library members which I can now reference.
Get the idea?
Applications
Much like libraries, it’s also quite common to have multiple applications running simultaneously on a single page. Banners, form handlers, custom UI elements, you name it. When these things need to communicate with each other, it becomes difficult to not use global variables.
Sure, if you have complete control over each component, and enough foresight to do so, you could probably write some clever application framework with all the right hooks so all these components can live in harmony together. But the moment the account person comes through your door demanding they need to hook in yet another third party component, all hope is lost.
Minimize, not eliminate
To conclude, I’d say your time as a programmer is best spent minimizing global variables rather than finding clever ways to eliminate them.
Don’t mistake this for being reckless. Just because JavaScript’s original intent was for everything to be globally linked doesn’t mean that it’s actually a good idea.
If you can eliminate them entirely, great. If you can keep it down to one or two, that’s not bad either. If you have 10 globals and you’ve followed the rules above you’ve done your best and are a responsible JavaScript programmer. Treat yourself to a cookie — you deserve it.
Pingback: Single var pattern – Javascript | malev's blog