Using 'window', 'document' and 'undefined' as arguments in anonymous function that wraps a jQuery plugin-Collection of common programming errors

Before answering in detail let me note that unlike other programming languages, javascript is a bit odd for two reasons: first, it was created in haste this meant lots of things didn’t get refined or implemented well. Second it was adopted by the internet very, very quickly and Microsoft copied the language very quickly and very accurately (including the bugs in the language). The result of this is that trying to correct mistakes in the design of the language was hard and/or impossible because they didn’t want to break compatibility with existing websites.

Now to go into the details:

What indeed is meant by function($)

Nothing special. In javascript function and variable names are allowed to use the letters a-z including uppercase, the numbers 0-9 and the symbols $ and _. There are no other restrictions on how they can be used. Though there are guidelines and conventions, some mentioned by the language spec itself, some grew with the programming community.

Therefore, $ is just a variable name. There is no difference between:

function foo ($) {alert($)}

and

function foo (x) {alert(x)}

It’s just the name chosen for the parameter. However, the spec strongly suggests that $ shouldn’t be used by code written by humans. It’s ok for computer generated code (a coffeescript compiler for example) but not ok for regular scripts. On the other hand it is strongly encouraged in scripts that use jQuery that $ always refer to the jQuery object (which incidentally happens to also be a function, that’s fine in javascript since functions are objects).

Since you’re writing jQuery the meaning of function ($) is an anonymous function that accepts one argument and the argument it expects is a jQuery object.

Why should I include window, document and undefined as arguments of function($)?

Arguably, one of the design mistakes in javascript is the lack of support for constants and/or immutable/protected variables/objects. As such, window, document and undefined are actually regular global variables – anyone can reassign them to anything.

The following is crazy but valid javascript code:

window = 42;

No sane programmer would do this but it’s possible none the less. The jQuery developers were very concerned by this and so jQuery tries its best to pass the real window, document and undefined into plugins in case anyone is crazy enough to do crazy things.

One of the features of javascript is that function arguments override global variables. So if any of the above variables have been hijacked by someone else they are reassigned to their proper names in the function.

If I do it, how do I access the actual window and document objects?

You are expected to pass the correct window, document and undefined as arguments named window, document and undefined into the function. Doing anything else means that you no longer have access to the window, document and undefined objects.

There are crazy workarounds that you can do to try go grab a hold of the window object (also know as the global object) and from there you can get a hold of document. The jQuery code is actually one workaround to get back undefined in case it has been hijacked.

undefined what, and why?

As you correctly stated. undefined is the value javascript gives to things that are declared but have no values assigned to them. But in javascript undefined is just a global variable. If you don’t touch it it initially has the value of undefined (circular logic, I know). But it can be modified:

undefined = 'boom!';

And henceforth all undefined variables will have the value of "boom!". The latest spec of the javascript language actually disallows reassigning to undefined but as of today only Safari does this.

Again, no sane programmer will do this.

Originally posted 2013-11-09 21:42:40.