What advantages does using (function(window, document, undefined) { ... })(window, document) confer? [duplicate]

Why are window and document being fed in instead of just being accessed normally?

Generally to fasten the identifier resolution process, having them as local variables can help (although IMO the performance improvements may be negligible).

Passing the global object is also a widely used technique on non-browser environments, where you don't have a window identifier at the global scope, e.g.:

(function (global) {
  //..
})(this); // this on the global execution context is 
          // the global object itself

Why the heck is undefined being passed in?

This is made because the undefined global property in ECMAScript 3, is mutable, meaning that someone could change its value affecting your code, for example:

undefined = true; // mutable
(function (undefined) {
  alert(typeof undefined); // "undefined", the local identifier
})(); // <-- no value passed, undefined by default

If you look carefully undefined is actually not being passed (there's no argument on the function call), that's one of the reliable ways to get the undefined value, without using the property window.undefined.

The name undefined in JavaScript doesn't mean anything special, is not a keyword like true, false, etc..., it's just an identifier.

Just for the record, in ECMAScript 5, this property was made non-writable...

Is attaching the object we're creating directly to window a particularly good idea?

It's a common way used to declare global properties when you are on another function scope.


This particular style does bring some benefits over the "Crockford" style. Primarily, passing window and document allows the script to be more efficiently minified. A minifier can rename those parameters to single-character names, saving 5 and 7 bytes respectively per reference. This can add up: jQuery references window 33 times and document 91 times. Minifying each token down to one character saves 802 bytes.

Additionally, you do get an execution speed benefit. When I first read @joekarl's assertion that it provides a performance benefit, I thought, "that seems rather spurious." So I profiled the actual performance with a test page. Referencing window one hundred million times, the local variable reference provides a modest 20% speed increase (4200 ms to 3400ms) in Firefox 3.6 and a shocking 31,000% increase (13 sec to 400ms) in Chrome 9.

Of course, you're never going to reference window 100,000,000 times in practice, and even 10,000 direct references only take 1ms in Chrome, so the actual performance gain here is almost completely negligible.

Why the heck is undefined being passed in?

Because (as mentioned by @CMS) the token undefined is actually undefined. Unlike null, it has no special meaning, and you're free to assign to this identifier like any other variable name. (Note, however, that this is no longer true in ECMAScript 5.)

Is attaching the object we're creating directly to window a particularly good idea?

The window object is the global scope, so that's exactly what you're doing at some point, whether or not you explictly write "window." window.Namespace = {}; and Namespace = {}; are equivalent.


I'm with you in using Crockford's style.

To answer your questions

1.Is there a particular advantage to encapsulating an object like this?

The only advantage I can see is by making window and document local variables instead of global variables, you get some added safety by not being able to directly overwrite either one and also some performance gain by them both being local.

2.Why are window and document being fed in instead of just being accessed normally?

Addressed above. Local variables tend to be faster, but with jit compiling these days thats becoming nominal.

3.Why the heck is undefined being passed in?

No clue....

4.Is attaching the object we're creating directly to window a particularly good idea?

Probably not, but I would still stick with Crockford's pattern as attaching the function to the window object exposes it to the rest of the global stack through the window object as opposed to exposing it through a non-standard namespace.