Global Domination
June 1, 2006 at 11:27 am by Douglas Crockford | In Development |JavaScript, as realized in browsers, is a load-and-go programming language. Programs are delivered to the execution site as text. This is a good fit for the web, which is at its root a text delivery system. The program text is eval‘d, which compiles it into an executable form and then immediately executes it. That execution can leave artifacts in the window’s global object.
The global object is the global namespace that holds the top level functions and global variables. Variables which are not explicitly defined are implied global variables, and their names are also kept in the global object. This was a convenience for the little scripts that Navigator 2 was expected to support. In the decade since NS2, those little scripts have grown into Ajax applications, and the true nature of the global object is revealed:
Global variables are evil.
Global variables are a source of unreliability and insecurity. Fortunately, JavaScript includes tools for allowing us to drastically minimize our use of globals, which makes our programs more robust. This becomes increasingly important as our programs get bigger, and as we mix in and mash up program components from multiple authors. Reducing our dependency on globals increases the likelihood that collisions are avoided and that the program components work harmoniously.
An objective measure of the quality of a JavaScript program is How many global variables and global functions does it have? A large number is bad because the chance of bad interactions with other programs goes up. Ideally, an application, library, component, or widget defines only a single global variable. That variable should be an object which contains and is the root namespace for all of your stuff.
Yahoo’s single global is YAHOO. It is spelled in all caps to identify it as something special, since all lower case is ordinary and initial caps indicates a constructor. Being in all caps, it is unlikely that someone would use it accidentally, which further reduces the likelihood of collision.
Yahoo is the world’s biggest website. Eventually, all of Yahoo’s JavaScript and browser webstate will be accessible through the YAHOO object.
But this technique also works well with the smallest library or widget. It is a clean, efficient way of organizing your program’s resources. The performance hit in having to access through a single global is negligible. JavaScript is very good at resolving such expressions. It is more than offset by the self-documentation and reliability benefits.
Generally a shallow tree is better than a deep tree. One could imagine that YAHOO.util.Dom.get could have been factored more compactly perhaps as YAHOO.get. And perhaps someday it will, but for now YAHOO.util.Dom.get is not measurably slower, and it is helping Yahoo to manage its evolving codebase. (And if you don’t like the length, you only have to type it once. See with Statement Considered Harmful.)
Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!
22 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.
Bravo for setting an example. Perhaps I can use this to prod my employer to move in a similar direction. Thanks!
Comment by Patrick Fitzgerald — June 1, 2006 #
I can’t agree less than 100%. Lots of global variables hanging around is one thing, and good quality JS code is another. And these two things rarely meet one another.
I would like to read more about global namespace pollution via prototype extension of native JS objects (String, Array, etc). Isn’t it equally bad? And what should be said for some very popular JS libraries that are doing just that?
Comment by Theodor Zoulias — June 1, 2006 #
Theodor Zoulias: Good point on the prototype extension of native objects. It’s conceivable that extending a string and/or some other object could potentially collide with another author’s extension of the same object.
However, I also agree with the Douglas that through namespacing you can avoid similar situations as pertaining to your own code.
Comment by Ara Pehlivanian — June 2, 2006 #
[…] Global namespaces are a pain, and so is global domination;-) […]
Pingback by Andre’s Blog » Blog Archive » Podcasting it up with the Redmonks — June 2, 2006 #
> I can’t agree less than 100%
What does that mean? Does that mean “you do agree more than 100%”? You disagree with less than whole?
> Lots of global variables hanging around is one thing, and good quality JS code is another
I’m not sure I fully understand that either. Indeed, lots of global variables is one thing, and quality code is another. When there is lots of global variables, then the quality of the code becomes bad (or is considered to not have as good of quality).
Typically when working with YUI utils I like to set up the following shortcuts in my own private scope of my applications:
MyApp.example = function() {var $E = YAHOO.util.Event;
var $D = YAHOO.util.Dom;
var $M = YAHOO.util.Motion;
var $ = $D.get;
return {
init : function() {
$E.on(['a','b','c'], 'click', this.fly, $('bar'), true);
},
fly : function() {
var attributes = {
width : { by : 50 },
height : { by : 50 },
points : { to : [100,200] }
};
var anim = new $A(this, attributes);
anim.animate();
}
};
}();
The greatest part of it is that it allows me to have my own amount of verbosity. The lookups come at a very, very small price.
Comment by Dustin Diaz — June 2, 2006 #
@Dustin Diaz:
Ok, I needlessly made overly complex a simple phrase. I just wanted to express my total agreement with Mr Crockford’s arguments. :-)
Your code snippet seems very elegant to me. But as far as I can understand your shortcut-using method makes your code faster, not slower. In other words the lookups come at a negative price I think.
Comment by Theodor Zoulias — June 3, 2006 #
Indeed Theodor, they actually do come at a very small negative price. I actually don’t mind the extra time - they are literally unnoticeable, even in larger files. You can profile the extra weight over a thousand lookups and see for yourself that it’s very small.
Comment by Dustin Diaz — June 3, 2006 #
Good article — and I agree with Theodor:
!(agreement
Comment by Peter Frueh — June 8, 2006 #
Dustin Diaz,
It is my understanding that variables starting with $ are intended for library code. Do you consider this a problem?
Comment by mwarden — June 11, 2006 #
Matt,
The ecmascript specs have something to say about the use of dollar sign.
“The dollar sign ($) and the underscore (_) are permitted anywhere in an identifier. The dollar sign is intended for use only in mechanically generated code. ”
http://www.ecma-international.org/publications/standards/Ecma-262.htm
section 7.6
According to this intention we are best not to start with $
Comment by peter michaux — June 24, 2006 #
I would like to see the middle namespace disappear in examples like YAHOO.util.Dom but I think it is worthwhile keeping YAHOO.Dom and not dropping the Dom.
Comment by peter michaux — June 24, 2006 #
[…] Reasons why this sucks: 1) it’s ugly, and 2) it makes the code much less portable, because whoever adapts it will have to ferret out every instance of MINDSACK.foo and substitute his own namespace. I was just about to punt the whole namespacing idea, until I ran across another post by Mr. Diaz, this one a reply to Douglas Crockford’s Global Domination article on the YUIblog: Typically when working with YUI utils I like to set up the following shortcuts in my own private scope of my applications: […]
Pingback by Mindsack » Blog Archive » Hacking Scope in Javascript — July 7, 2006 #
> Ideally, an application, library, component, or widget defines only a single global variable.
Agreed, but how does it define the global variable?
1: var YAHOO = {};
2: YAHOO = {};
3: window.YAHOO = {};
4: self.YAHOO = {};
I think #2 is the best way, but what is the reason for using #1 in YUI?
Comment by Andrea Ercolino — February 7, 2007 #
I like #1 because it doesn’t look like an accident. I don’t like JavaScript’s implied global policy; I think it was a mistake. So I like all declarations, including global declarations, to be explicit.
Comment by Douglas Crockford — February 9, 2007 #
OK, but if I document it, then anyone can see it’s intentional:
YAHOO = {}; //implied global
—
I think the YAHOO’s declaration can be improved:
switch( typeof YAHOO ) {
case "undefined":
var YAHOO = {};
break;
default:
YAHOO = {}; //a proper re-definition
}
Comment by Andrea Ercolino — February 9, 2007 #
[…] Global variables are evil. Within YUI, we use only two globals: YAHOO and YAHOO_config. Everthing in YUI makes use of members within the YAHOO object hierarchy or variables that are scoped to such a member. We advise that you exercise similar discipline in your own applications, too. […]
Pingback by A JavaScript Module Pattern » Yahoo! User Interface Blog — June 12, 2007 #
[…] (When in doubt, wrap it in a closure. Global variables are evil.) […]
Pingback by Foo Hack » YUI’s “Module Pattern” vs. Prototype’s Class Function — August 13, 2007 #
[…] doesn’t obfuscate global symbols, and 2) you won’t pollute the global object (see this great article by Douglas […]
Pingback by Julien Lecomte’s Blog » Introducing the YUI Compressor — August 14, 2007 #
[…] Global Domination, an article written by Douglas Crockford […]
Pingback by zachleat.com {web} » Namespacing outside of the YAHOO Namespace — August 28, 2007 #
>>OK, but if I document it, then anyone can see it’s intentional:
Comments are not durable. I’ve known programmers who strip all comments upon opening a source file. The justification they give? “Comments are always wrong.” My translation of that is that code can be changed without changing the comments, so the comments don’t necessarily apply to the code that you see.
Making the code clear enough that it doesn’t need comments is the best way to go.
Comment by timothy — January 31, 2008 #
[…] 编写可重用的、优秀的JavaScript代码,其关键在于对名称空间的积极把控。JavaScript只拥有单一的、全局的名称空间(即window对象),而很多程序员(以及一些库)恣意地为之添加各种东西。要知道全局变量是魔鬼!聪明的开发人员,会使用类似组件模式的技术,来尽力减少全局对象的数量。 […]
Pingback by Vayn技术网摘 » 窥探jQuery — February 10, 2008 #
[…] to use namespaces when writing your JavaScript. The reasons why have been stated time and again by much smarter and more eloquent people than myself, so suffice it to say, you should do […]
Pingback by Dr. Prolix » Blog Archive » Enliven your namespaces — May 1, 2008 #