Tuesday, November 8, 2011

thoughts on keeping the global namespace clean

So one well known issue with javascript is that it's a bit too easy to pollute the global namespace.

Personally I find this is a big issue more in theory than in practice, choose reasonably distinct function and variable names, and you hardly ever have a problem.

Half the problem is that if you just start using a variable without a "var" declaration, it gets slapped into the global namespace. Douglas Crockford, among others, considers it a bit of misstep in the design of the language.

(The other half of the problem is the same "bootstrapping" problem any language faces: how do you tell the system where code execution starts, and where is the tree of object and functions rooted ? C and Java have their main(); in Javascript, you can start putting function declerations and even calls anywhere, in practice there's a lot of $(document).ready(function(){}); )

So, you can go a little crazy with loaders and tools to control your namespace and keep your private variables and functions private etc, and also with CreateDelegate() functions to pass thing to page elements and whatnot. This is overkill for most projects where you're more interested in the functioning of the site than making a reusable toolkit. (YMMV). A good compromise is "make one global variable per functional grouping". For example, today I was working on a "madlibs" controller (for eventual integration as a WordPress plugin) Part of the code for that was:
var ao_madlibs = new function(){
  this.neededEndpoints = {};
  this.doMadLibs = function(){
//CODE GOES HERE
    } //end doMadLibs
 }//end ao_madlibs


In practice I find this a good balance of control and ease of reading. One caveat, in the doMadLibs code I used jQuery's .each() function, and in the anonymous function in there, "this" had a different meaning, so I had to use the global reference ao_madlibs.


I was looking at a bit of coworkers' code... he's more of an architect, and cribbed this from FB's api code:

if (!window.AO) {
    window.AO = {
    processElements : function(){
                  //do something
        },

        someVariable: {}
   };
}
This code is using more of the associative array syntax, plus doing that check to make sure it's only called once. I find it's a little more "foreign" looking to me, but makes a good amount of sense if you're used to JS's variable syntax. Pick your poison I guess! Sometimes I do miss Java's class structure syntax...


The nice thing about using a global variable, to, is that you can really easily and concisely refer to your "functional grouping" in page elements and in other parts of your system, again without worrying about ever-changing meaning of "this" and using tons of oddball CreateDelegate functions... I find KISS (Keep it Simple Stupid) to be an important principle in making code I can read in the future, and in communicating my intent to other people looking at my code.

No comments:

Post a Comment