thomasfrank.se

Find your global namespace

June 25, 2006

Experienced JavaScripters often say that you should not clutter the global namespace. So it would be nice to know just how cluttered your global namespace is, wouldn't it? But finding all the variables in your global namespace used to be hard, especially in Internet Explorer. Now I'm making it easy for you.
To start with, I will let you have a look at my global namespace. (And I admit it is a bit cluttered.) Just press the Own-button below and you will se all the global variables I'm responsible for on this page.

Do you want to check out my global namespace?
Press one of the buttons above:
  • Clear -- clears the list and shows this explanation.
  • Native -- variables native to the browser/DOM.
  • Own -- variables defined by this web page.
  • All -- all the global variables.

Using my script

If you want to have a look at your own global variables --download this script (2.5 kB) and embed it as the first script on your page. This is really important -- if it is not first you won't get a correct separation of your own variables from the native variables:
<head>
<script type="text/javascript" src="globalVars.js"></script>
...
</head>

The script adds a global object called globalVars. Here is an example of how to use that object:
var win=globalVars.getOwn();  /*returns an object containing global variables*/
var x=[];
for (var i in win){x.push(i)};
alert(x.join("\n"));

So the getOwn()-method returns an object containing global variables. Actually there are three different methods that you can chose between:

A slight clash with the Object.prototype

If we add members to the Object.prototype this gets treated a bit differently in different browsers. In IE they don't get to become global variables, in most other browsers they do. However the object returned by the globalVars methods always include them. To avoid this -- add a check like:
if (window[i]!=undefined){x.push(i)};

Cross browser compatibility

This script has been tested in IE6, IE7beta2, Firefox 1.5, Safari 2, Opera 8, Opera 9 and Netscape 7.
The getOwn() method should return exactly the same variables in different browsers if your script does not contain any browser/DOM-sniffing, where you set different global variables depending on browser features.

Behind the scenes -- how did I get it to work?

In web browsers the global namespace is equivalent with all the members of the window object. Our first guess would be that we should be able to find all of its members by doing:
var x=[];
for (var i in windows){x.push(i)};
alert(x.join("\n"));

Well, it turns out this doesn't work in JScript/IE at all, because non-native variables are not found when we try to enumerate the window object. You can read more about this in Eric Lippert's blog.

A workaround for IE

The first thing I had to do was to write a workaround for IE browsers. In IE it is possible to get the complete script source for a page by looking at the document.scripts array.
If an element has no innerHTML value, then it is an external script and we can load the source with a simple AJAX request. We then use a little bit a regular expression magic to extract every "word" from the source(s) and check if these words exists as global variables. This works suprisingly well.

Filtering out DOM defined variables

All web browsers return a lot of variables that the are defined from scratch in the DOM. A few more get defined around "onload time" when the document is complete. And some (predominantly in Opera and Safari) get added when we manipulate html elements dynamically.
Filtering out all of these from our own variables is tougher than it seems at first. Especially if you want the exact same behaviour in all browsers. But I fiddled with it for some time and now it seems to work in a consistent manner in most modern browsers, thought I strongly suspect the script will need further modification as new browser versions see the light of day.
[comments]