How Does This JavaScript/Jquery Syntax Work: (Function( Window, Undefined ) { })(Window)

How does this JavaScript/jQuery syntax work: (function( window, undefined ) { })(window)?

The undefined is a normal variable and can be changed simply with undefined = "new value";. So jQuery creates a local "undefined" variable that is REALLY undefined.

The window variable is made local for performance reasons. Because when JavaScript looks up a variable, it first goes through the local variables until it finds the variable name. When it's not found, JavaScript goes through the next scope etc. until it filters through the global variables. So if the window variable is made local, JavaScript can look it up quicker.
Further information: Speed Up Your JavaScript - Nicholas C. Zakas

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

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.

What does following a function with (jQuery, window, document); mean?

It's called a 'self ivoking' or 'immediately invoked' function. It means that the function is run as soon as it is created using the parameters in the final set of brackets.

Further information

How to override window and undefined in javascript?

Try this

function test () {
var undefined = 2; // 2
console.log(undefined == 2); // true

var window = 5; // 5
console.log(window == 5); // true
}

I believe you can alter the value of undefined and window inside a function, but not in the global scope

Difference between (function(window){}) and (function(){})

The semantic difference is small in this case. However, if window is used a lot throughout the code, aliasing it as a local variable allows for better minification.

(function (window) { window['foo'] = window['baz']; })(window);

can be minified to

(function(w){w['foo']=w['baz']})(window)

Without the local alias, window could not be reduced and the minification would instead be

(function(){window['foo']=window['baz']})()

There are other reasons as well as other use-cases for similar tricks. Have a look at this question to find more in-depth explanations.

jQuery question: what does it really mean?

There are already two answers but this is my guess on the missing end of the code:

(function ($, window, undefined) {
// ... jquery code...
})(jQuery, window);

Note: three parameters are expected but two are supplied.

What it basically does is:

  1. gives a private scope inside curly braces, so any var declared inside is not visible outside
  2. makes a private $ shortcut to jQuery without relying on this shortcut being set globally (eg. jQuery.noconflict() might have been called and this would still work)
  3. makes a lexical window variable that would mean faster lookups for global variables
  4. makes sure that undefined is indeed undefined in the scope between curly braces, even if someone has written something like undefined = "now it's defined"; in the global scope, because undefined can actually be redefined (this is a mistake of the language).

This pattern is known as immediately invoked function, or immediate function for short, or self-invoking anonymous function, or some other names. The basic idea is that:

(function (x, y) {
// ...
})(1, 2);

or:

(function (x, y) {
// ...
}(1, 2));

means the same as:

function myFunction (x, y) {
// ...
}
myFunction(1, 2);

but without the need to give any name to your function and pollute the namespace.

Going back to your question, this doesn't mean $(document).ready() or anything like that, but it means that you can use $(document).ready() inside instead of jQuery(document).ready() even if the $ shortcut is not available outside.

This example may actually explain it better, even if it isn't used anywhere:

(function (JQ, window, undefined) {

JQ(document).ready(function () {
// this is run when document is ready
});

})(jQuery, window);

Now instead of $ you can call jQuery as JQ and use JQ(document).ready() instead of $(document).ready() – it may not seem very useful but it shows what happens when you have a code like that.

As a side note I might add that thanks to this pattern you don't actually need variable declarations in the language but only function arguments. Instead of:

var x = 10;
alert(x * x * x);

you could use:

(function (x) {
alert(x * x * x);
})(10);

and indeed a function like this:

function square (x) {
// some code ...
var result = x * x;
return result;
}

is exactly equivalent to:

function square (x, result) {
// some code ...
result = x * x;
return result;
}

because of the hoisting mechanism in JavaScript that would make the result variable available (but undefined) even before the declaration and assignment in both cases (in the // some code ... part). This is often a source of confusion but is actually quite interesting and extremely powerful.

See also my other recently updated answer to the question:
Help understanding JavaScript global abatement techniques for more info on this subject.

What is this javascript notation?

The first semi-colon ; sets the following code apart from any other preceding code that may have forgot the semi-colon. This is important as the parens will try to run the previous statements as a function if the semi colon was not found.

For the rest of the code, we are just declaring an "in-line" function which will be immediately executed where the arguments $, window, document are then instantiated as jQuery, this, this.document (respectively) from the global scope. This is primarily so that you can use "$" within your new jQuery plugin without worrying if $ has been overwritten somewhere else. You can be sure that $ is the same as jQuery.

Read more about "Protecting the $ Alias and Adding Scope" here

Update from OP:

For the if statement returning false, be sure that your html is loaded at the time of calling your if statement. One quick way to do this, is to wrap it in a $(document).ready method like so:

$(document).ready(function () {
if($('ul.mtree').length) {
alert("got 'em!");
}
});

Understanding undefined as argument

In older browsers, undefined wasn't immutable or non-writable. Setting undefined as a name for an unused function parameter meant that it was undefined, even if it got set in a higher scope.

// Old browser
undefined = 1;
undefined; // 1

// Modern browser
undefined = 1;
undefined; // undefined

It should be noted that the non-writability is only applicable in the global scope, in both cases the following is true;

(function () {         // creating a new scope means..
var undefined = 1; // this is now different to the `undefined` global
return undefined; // so can be written to, e.g. set as 1
}()); // 1


Related Topics



Leave a reply



Submit