Global Domination, Part Two
April 16, 2008 at 1:29 pm by Douglas Crockford | In Development |As I continue the practice of the craft of programming, I am always examining my practices. Can I improve the patterns that I use so that I can make my programs clearer, stronger, better? This is particularly important when working with a language like JavaScript which has a bias that favors patterns that are confusing, weak, and worse.
One of the worst features of JavaScript is its reliance on global variables. This can be mitigated with global abatement and the module pattern, which can significantly reduce the number of global variables that we need to declare.
But when we must declare a global variable, how best should we do that? JavaScript provides three ways of declaring a global variable, and they all have problems. Which is least worst?
The first is to assign to a new name outside of any function.
pity = {}; // The first form
The second is to use the var keyword outside of any function.
var pity = {}; // The second form
The third is to assign to a property of the global object.
this.pity = {}; // The third form
All three forms do the same thing. (There is also a fourth way, the abominable implied global, but we will not speak of that here. And don’t get me started on the fifth and sixth ways.)
So, given three ways to do the same thing, which should we use? I used to favor the second way. It looked to me the clearest in stating (or at least suggesting) my intention to declare something.
But it wasn’t completely satisfactory. First, some people read var in that
position as declaring the variable in the scope of the compilation unit, similar
to the way static works in C. This would be a useful reading, except that
JavaScript does not have compilation unit scope. A knowledgeable programmer
should know that, but an alarming percentage of web developers program in
ignorance of the language, so this is a mild concern.
A greater concern is that the second form is larger than the first form, but does the same thing. Generally, I prefer minimal forms.
But the thing that finally convinced me that the first form is the least worst is that IE gets the second form wrong, so that responsibly adaptive programs fail when using constructs like
var pity = this.pity || {};
In order to be maximally productive, I want to avoid features that have portability problems. It took me too long to accept that the second form is problematic and should therefore be avoided.
The thing I liked about the second form was that it seemed more intentional.
By typing var, I declared that this isn’t an accidental misspelling. I am
intentionally declaring a new global variable. But JavaScript paid no attention.
I still feel the need to state that intention, so I state it in a comment.
/*global pity*/
pity = {};
JSLint is able to understand that comment, and can alert me to any global variables that I did not intentionally declare. That gives me confidence that I am not making a common mistake. The second form made me feel good, but didn’t actually give me any real assurance.
I am still learning how to program. I read code, and I consider the opinions of other programmers. I still have the capacity to change my practices. It is hard sometimes to admit that my previous practices were weak. But that is more than offset by adopting practices that are stronger.
Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!
3 Comments »
RSS feed for comments on this post. TrackBack URI
Leave a comment

Copyright © 2007 Yahoo! Inc. All rights reserved. Privacy Policy - Terms of Service
Powered by WordPress on Yahoo! Web Hosting.
Testing the comment system, which was down for a while there. Everything seems back to normal, though, so give it a go!
Comment by Administrator — April 21, 2008 #
I would think that it is common knowledge to check
typeof pity === 'undefined', instead of using a construct likevar pity = this.pity || {};, especially assuming that the code in question is the byproduct of a reasonably adaptive program.If you assume that the web developer audiences that program in ignorance of the language and the readership of this blog (or the readership of any JavaScript blog author who adopts this method) are mutually exclusive, then one might trend towards agreeing your third form is appropriate.
But, seeing that most developers “learn” from copy and paste, it would seem that the second form would be safer, if for no other reason than to prevent those abominable globals we all abhor.
Comment by Zach Leatherman — April 21, 2008 #
The “var pity = this.pity || {}” and it’s variants has become quite popular in recent Javascript libraries, and I like it myself. You’ll have to give in to the assumption that you use it in places where booleans are not values you expect.
One of the most useful cases for me would be as a default value for function parameters. Consider:
function doSomething (a) {
a = a || ‘defaultValue’;
}
If the variable ‘a’ is undefined here, it will get a default value instead, making the variable ‘a’ useful to the rest of the function.
Though if you prefer, I guess it could be written as:
function doSomething (a) {
a = (a !== undefined ? a : ‘defaultValue’);
}
Comment by Frode Danielsen — May 1, 2008 #