jQuery function syntax: passing 'undefined' and expression in brackets [duplicate] - javascript

Have you ever taken a look under the hood at the jQuery 1.4 source code and noticed how it's encapsulated in the following way:
(function( window, undefined ) {
//All the JQuery code here
...
})(window);
I've read an article on JavaScript Namespacing and another one called "An Important Pair of Parens," so I know some about what's going on here.
But I've never seen this particular syntax before. What is that undefined doing there? And why does window need to be passed and then appear at the end again?

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

Undefined
By declaring undefined as an argument but never passing a value to it ensures that it is always undefined, as it is simply a variable in the global scope that can be overwritten. This makes a === undefined a safe alternative to typeof a == 'undefined', which saves a few characters. It also makes the code more minifier-friendly, as undefined can be shortened to u for example, saving a few more characters.
Window
Passing window as an argument keeps a copy in the local scope, which affects performance: http://jsperf.com/short-scope. All accesses to window will now have to travel one level less up the scope chain. As with undefined, a local copy again allows for more aggressive minification.
Sidenote:
Though this may not have been the intention of the jQuery developers, passing in window allows the library to be more easily integrated in server-side Javascript environments, for example node.js - where there is no global window object. In such a situation, only one line needs to be changed to replace the window object with another one. In the case of jQuery, a mock window object can be created and passed in for the purpose of HTML scraping (a library such as jsdom can do this).

Others have explained undefined. undefined is like a global variable that can be redefined to any value. This technique is to prevent all undefined checks from breaking if someone wrote say, undefined = 10 somewhere. An argument that is never passed is guaranteed to be real undefined irrespective of the value of the variable undefined.
The reason to pass window can be illustrated with the following example.
(function() {
console.log(window);
...
...
...
var window = 10;
})();
What does the console log? The value of window object right? Wrong! 10? Wrong! It logs undefined. Javascript interpreter (or JIT compiler) rewrites it this way -
(function() {
var window; //and every other var in this function
console.log(window);
...
...
...
window = 10;
})();
However, if you get the window variable as an argument, there is no var and hence no surprises.
I don't know if jQuery is doing it, but if you are redefining window local variable anywhere in your function for whatever reason, it is a good idea to borrow it from global scope.

window is passed in like that just in case someone decides to redefine the window object in IE, I assume the same for undefined, in case it's re-assigned in some way later.
The top window in that script is just naming the argument "window", an argument that's more local that the global window reference and it what the code inside this closure will use. The window at the end is actually specifying what to pass for the first argument, in this case the current meaning of window...the hope is you haven't screwed up window before that happens.
This may be easier to think of by showing the most typical case used in jQuery, plugin .noConflict() handling, so for the majority of code you can still use $, even if it means something other than jQuery outside this scope:
(function($) {
//inside here, $ == jQuery, it was passed as the first argument
})(jQuery);

Tested with 1000000 iterations. This kind of localization had no effect in performance. Not even a single millisecond in 1000000 iterations. This is simply useless.

Related

What is the purpose for passing "window" and "undefined" to a function? [duplicate]

Have you ever taken a look under the hood at the jQuery 1.4 source code and noticed how it's encapsulated in the following way:
(function( window, undefined ) {
//All the JQuery code here
...
})(window);
I've read an article on JavaScript Namespacing and another one called "An Important Pair of Parens," so I know some about what's going on here.
But I've never seen this particular syntax before. What is that undefined doing there? And why does window need to be passed and then appear at the end again?
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
Undefined
By declaring undefined as an argument but never passing a value to it ensures that it is always undefined, as it is simply a variable in the global scope that can be overwritten. This makes a === undefined a safe alternative to typeof a == 'undefined', which saves a few characters. It also makes the code more minifier-friendly, as undefined can be shortened to u for example, saving a few more characters.
Window
Passing window as an argument keeps a copy in the local scope, which affects performance: http://jsperf.com/short-scope. All accesses to window will now have to travel one level less up the scope chain. As with undefined, a local copy again allows for more aggressive minification.
Sidenote:
Though this may not have been the intention of the jQuery developers, passing in window allows the library to be more easily integrated in server-side Javascript environments, for example node.js - where there is no global window object. In such a situation, only one line needs to be changed to replace the window object with another one. In the case of jQuery, a mock window object can be created and passed in for the purpose of HTML scraping (a library such as jsdom can do this).
Others have explained undefined. undefined is like a global variable that can be redefined to any value. This technique is to prevent all undefined checks from breaking if someone wrote say, undefined = 10 somewhere. An argument that is never passed is guaranteed to be real undefined irrespective of the value of the variable undefined.
The reason to pass window can be illustrated with the following example.
(function() {
console.log(window);
...
...
...
var window = 10;
})();
What does the console log? The value of window object right? Wrong! 10? Wrong! It logs undefined. Javascript interpreter (or JIT compiler) rewrites it this way -
(function() {
var window; //and every other var in this function
console.log(window);
...
...
...
window = 10;
})();
However, if you get the window variable as an argument, there is no var and hence no surprises.
I don't know if jQuery is doing it, but if you are redefining window local variable anywhere in your function for whatever reason, it is a good idea to borrow it from global scope.
window is passed in like that just in case someone decides to redefine the window object in IE, I assume the same for undefined, in case it's re-assigned in some way later.
The top window in that script is just naming the argument "window", an argument that's more local that the global window reference and it what the code inside this closure will use. The window at the end is actually specifying what to pass for the first argument, in this case the current meaning of window...the hope is you haven't screwed up window before that happens.
This may be easier to think of by showing the most typical case used in jQuery, plugin .noConflict() handling, so for the majority of code you can still use $, even if it means something other than jQuery outside this scope:
(function($) {
//inside here, $ == jQuery, it was passed as the first argument
})(jQuery);
Tested with 1000000 iterations. This kind of localization had no effect in performance. Not even a single millisecond in 1000000 iterations. This is simply useless.

JavaScript Anonymous Constructor Function: !function(){}();

I've seen this syntax for creating an anonymous constructor function in JavaScript:
var Application = Application || {};
!function(window, Application) {
Application.property = {/*...*/}
Application.method = function(){/*...*/}
}(window, Application);
I want to understand what the following parts here:
What is the advantage of using first line (i.e. var o = o || {};) vs just stating var o = (function(){})();?
Why ! is used in front of function?
Why would I pass window or Application as parameters when they are global object?
Is this the most convenient way for anonymous constructor function and how is this better than:
4a)
var Application = {
property: {},
method: function(){}
}
or 4b)
var Application = (function() {
var method = function(){/*...*/}
return {method:method};
}());
The first line is to ensure that Application always exists, and is generally used in cases where it's expected that Application already should exist, and the function just augments the existing object. If it doesn't exist, this makes sure that we don't get an error for accessing properties of undefined. Your examples are only equivalent in the case where Application does not yet exist. In all other cases, your code will obliterate the existing Application, which is almost certainly not the intent.
The comment from Vatev explains what the ! does. It's another syntax for making the function in question become a self executing anonymous function. (Incidentally, it also takes the return value of the function - which is currently undefined, and flips its truthyness, so it evaluates as true. Since the result isn't stored in any variable, though, that's clearly not the purpose.)
Finally, why pass window and Application into the function and use it there? This is a safety feature, in case other code changes window or Application later on. It guarantees that within the anonymous function, window and Application are exactly what you expect it to be. In the shorthand example you gave, this may appear to not matter - after all, why protect these variables if you're using them immediately and not storing them? In many cases, you return something from this function, and then window and Application would be stored in the closure, so you'd retain the variables. It makes it safe from people who later on decide to say Application = {...}.
I don't know all of the answers but I'll try to answer what I can.
Using var Application = Application || {}; simply means that you are dealing with scope. If the "Application" variable has already be defined, it will just mean that it inherits and is now available in the current scope. If not, the "||" part (means OR) means that it will be created as an empty object. You are dealing with creating an object and then acting on it, not just having the result given back raw. That's why you shouldn't use "o = (function() {...});". "o" would then be the result of the function and not the object.
The use of "!function" causes it to be treated as an expression, but this can be tricky because you may have to think in opposites. E.g. !null means you are checking that it isn't null, not that you are checking for it to be null.
Passing in the window and Application objects deal with scoping, again. It is explicitly passing them into the function, then returning them at the end. Think of this as putting clothes in the washing machine. You put them in, stuff can happen, then you get them back out. It's a really crude idea and isn't the best example, but it's how I thought of it a while back. You put clothes in, call then rinse function, then soap function, then rinse again, then spin to drain water.
Hopefully someone else can answer that, I'm not sure what the differences are.
Since two answers so far neglected these two details: A pattern used by libraries like jQuery is using the following two parameters:
(function (window, undefined) {
window.myPlugin = ...;
})(window);
There are two things going on here:
undefined is specified as a parameter, but not passed in. This way, undefined is guaranteed to have th expected value within the inner scope. This is only necessary for older browsers which allowed overwriting undefined (though it has always been considered bad practice to do so – it's just what libraries like jQuery do to avoid other code interfering with their code).
Aliasing a global object like window within the scope allows the code to be minified more (also works for undefined). Obviously, the more references you have to the aliased object(s), the more you will save:
.
(function(w,u){w.myPlugin=...;w.somethingElse=...;if(whatever===u){return;}})(window);
compared to
(function(){window.myPlugin=...;window.somethingElse=...;if(whatever===undefined){return;}})();
You won't save much with window since typically you don't wanna clutter the global object up anyway. But aliasing undefined can save you quite some space.

What does the global in (function(global){ some code .. })(this) do?

I was looking at adding comments to JSON and found this script that strips them out before processing making the JSON valid. I am just trying to understand how it works to make the JSON.minify() function available?
It starts with
(function(global){ ...
totally which is weird to me. I found that "global is a property of a RegExp instance, not the RegExp object" on MDN but I don't understand how it is works in this script if at all.
This snippet:
(function(global){
// your code here
// referring to the variable named "global" in this scope
// will be a reference to the default javascript global object
})(this);
is a construct for assigning the global object (whatever it might be) to an argument labeled global for all code that is inside this self-executing function.
The self executing function is used to define a separate execution scope so that any functions or variables you define inside this other scope will not interfere with or be directly accessible from outside this scope (insulating your scope from other code scopes).
In a browser, the global object is the window object, but if you intended to have code that might work in other javascript environments (like no node.js on a server) where the global object might not be window, this is a way of extracting the global value from the default this value, putting it into another variable which you can then refer to anywhere inside your code block.
For code mean to only run in a browser, there really is no point to this. You can just refer to window when you need the global object.
It's just a function parameter name. It might as well be froozboggles.
This code:
(function(foo) {
// In here, what's called "bar" in the outer scope is called "foo"
})(bar);
Defines an anonymous function taking one parameter bar and immediately calls it with the value of bar as the first parameter.
Apart from what jfriend00 mentions in his fine answer, it's also a good way of making sure that you don't leak variables and functions to the outer scope: If you declare, say, var baz = 17; in the top scope in javascript, it will be a property of window. If you wrap it in a function as in the pattern you mention, you can only export properties to window explicitly -- by assigning them to global, in the case of your example. Edit: As #josh3736 says in his comment, you can also leak to window by assigning without a previous declaration, e.g. quux = 4711;.

What is the purpose of the anonymous function wrapper in jQuery?

jQuery starts off wrapping all of it's code in an anonymous function:
(function ( window, undefined) {
/*
...jquery code...
*/
}) (window);
I get that the function is executed immediately upon the entire script being read, but what is the purpose of the arguments? One is a global object reference, the other is a property reference.
Now, I remember that earlier in the script development, undefined actually got defined as something else (am I remembering that right?). Was that related to this?
Also, it looks like the function is being used as an operator? Just like it is above, I don't understand the syntax of the statement at all. Maybe there is context that would help?
The wrapper does a number of things:
function(window,undefined)
provides the window and undefined variables to the function
the anonymous call })(window); passes the window variable to the script.
If a user overrides the window object, they will easily be able to modify the script to use the correct window variable i.e.:
(function(window,undefined){})(w);
The lack of a second parameter being passed sets the undefined variable to have a value of undefined which prevents a programmer from messing up jQuery by overriding undefined.

Benefit of using 'window' prefix in javascript

Are there any benefits to using the 'window' prefix when calling javascript variables or methods in the window object? For example, would calling 'window.alert' have an advantage over simply calling 'alert'?
I can imagine using the prefix could give a small performance boost when the call is made from inside some function/object, however I rarely see this in people's code. Henceforth this question.
This is useful when attempting to test global object values. For example, if GlobalObject is not defined then this throws an error:
if(GlobalObject) { // <- error on this line if not defined
var obj = new GlobalObject();
}
but this does not throw an error:
if(window.GlobalObject) { // Yay! No error!
var obj = new GlobalObject();
}
Similarly with:
if(globalValue == 'something') // <- error on this line if not defined
if(window.globalValue == 'something') // Hurrah!
and:
if(globalObj instanceof SomeObject) // <- error on this line if not defined
if(window.globalObj instanceof SomeObject) // Yippee! window.prop FTW!
I would not expect to see a significant performance difference, and the only other reason you might do this is to ensure that you are actually getting a value from the global scope (in case the value has been redefined in the current scope).
I doubt there is any measurable performance benefit. After all the scope chain would be scanned for the identifier window first then the window object would be scanned for the desired item. Hence more likely it would be deterimental to performance.
Using window prefix is useful if you have another variable in scope that would hide the item you may want to retrieve from the window. The question is can you always know when this might be? The answer is no. So should you always prefix with window? What would you code look like if you did that. Ugly. Hence don't do it unless you know you need to.
Retrieved from Google (http://www.techotopia.com/index.php/JavaScript_Window_Object):
The window object is the top-level object of the object hierarchy. As such, whenever an object method or property is referenced in a script without the object name and dot prefix it is assumed by JavaScript to be a member of the window object. This means, for example, that when calling the window alert() method to display an alert dialog the window. prefix is not mandatory. Therefore the following method calls achieve the same thing:
window.alert()
alert()
However, I read but have not had time to test the following from:
(http://www.javascriptref.com/reference/object.cfm?key=20)
One place you'll need to be careful, though, is in event handlers. Because event handlers are bound to the Document, a Document property with the same name as a Window property (for example, open) will mask out the Window property. For this reason, you should always use the full "window." syntax when addressing Window properties in event handlers.
As far as performance, I think AnthonyWJones has it covered.
One use of the window prefix is to explicitly make something available outside the current scope. If you were writing code in a self-invoking function to avoid polluting the global scope, but there was something within that you did want to make globally available, you might do something like the following:
(function(){
function foo(){
//not globally available
}
function bar(){
//not globally available
}
window.baz = function(){
//is globally available
foo();
bar();
};
})();
I imagine that the performance benefit here is amazingly insignificant at best, if there is one at all.
It only matters if you're using frames and doing a bunch of javascript calls across frames, and even then only specific scenarios warrant the necessity of referencing window explicitly.
When you use the prefix, you're making it explicit you're using the "global" definition of the variable, not a local one. (I'm not sure whether / how you can inject variables into a scope in JS, except the weirdness with this and inline event handlers.) YMMV, you may either prefer the clarity, or find it to be just clutter.

Categories