Globals are bad

Globals are bad Mkay?

Most web devs know that polluting the global namespace can cause all kinds of problems. There are lots of ways to avoid it and lots of great articles about it. In short, having lots of properties of the window object can cause conflicts.

This tip bit attempts to help you identify global variables that you didn’t intend to be global.

First let’s cover the three ways you can attach something to the global namespace:

on the variable object

var myVar = ‘a value’;

implicitly

myVar = ‘a value’;

explicitly

window.myVar = ‘a value’;

Many of us generally avoid this problem in our applications via app namespacing or via module loaders such as Browserify and Require. However there might be occasions when you’re not working with one of these frameworks or you have mistakenly returned something to the global namespace. So, how do we find these pesky and potentially problematic properties?

The obvious way to see what properties belong to window is to, well, check what properties it has. In Chrome you can just type

Object.keys( window );

For something more cross browser compatible we can just do

var globalObjProps = [];
for (var prop in window) {
 if (window.hasOwnProperty(prop)) {
  globalObjProps.push(prop);
 }
}
console.log(globalObjProps);

Here I’m pushing all the properties into an array and logging that, which gives me this:

[“top”, “location”, “document”, “window”, “external”, “chrome”, “speechSynthesis”, “caches”, “localStorage”, “sessionStorage”, “webkitStorageInfo”, “indexedDB”, “webkitIndexedDB”, “crypto”, “applicationCache”, “performance”, “styleMedia”, “defaultstatus”, “defaultStatus”, “screenTop”, “screenLeft”, “clientInformation”, “console”, “devicePixelRatio”, “outerHeight”, “outerWidth”, “screenY”, “screenX”, “pageYOffset”, “scrollY”, “pageXOffset”, “scrollX”, “innerHeight”, “innerWidth”, “screen”, “CSS”, “navigator”, “frameElement”, “parent”, “opener”, “length”, “frames”, “closed”, “status”, “toolbar”, “statusbar”, “scrollbars”, “personalbar”, “menubar”, “locationbar”, “history”, “name”, “self”]

Rummaging through all these to see if any of them look like they’re from my app code doesn’t sound like a fun job though. What we need is a utility which shows everything except all that gubbins.

It seems a certain Mike Pouncey has kindly written a handy utility which checks such things for us called, you guessed it, badglobals. Download the gist to your app and include badglobals.js before your others scripts, then in the console run

BADGLOBALS.check()

Using the HTML5 boilerplate I get back $ and Jquery. Handy eh? Now I can clearly see what non-standard properties are assigned globally.

Let’s do a little test. Let’s create three global variables in our app code:

var aVarGlobal = ‘a global set with var’;
aGlobal = ‘a global set without var’;
window.aGlobalWindow = ‘a global set via window’;

and then run the check again. You’ll see that aVarGlobal is not listed because it used the var keyword.

The script is working as expected but you may want to see these global variables too. No problem, just use the command

BADGLOBALS.report()

and you’ll get back an object with the properties the good, the bad and the skipped — I soooo wanted to say ugly here. If you look inside the good array you’ll see aVarGlobal.

The object returned by running BADGLOBALS.report

So, if you’re ever concerned that you have conflicts in your global namespace or you’re just curious about what might be there try this gist and shed some light on this murky world.

You can download a repo which inlcudes the necessary files and test code here https://github.com/zone/global-ns-demo

Note that modernizr is loaded above the badglobals script and is therefore excluded from the check.

If you have any nice techniques for checking the global namespace please share them via the comments.