Why JavaScript file starts with (function (undefined)? [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

Declare variable so that would be it visible in global context but not belong to window or gett

I need to emulate in firefox the behavior of activeXobject in last versions of ie. I write addon with contentScript and want to implement to pages such variable. It is exactly what I want - It is a challenge in itself.
Example of IE 11 working code:
if (window.ActiveXObject == undefined) {
var but = new window.ActiveXObject; // [ActiveXObject object]
}
I need exactly same behavior in firefox with my variable
For example what i want
<script>
console.log(window.variable) // undefined
console.log(new window.variable); // [object Variable]
console.log(new variable) // [object Variable] if not possible previous string
</script>
for solving, you can change the addon sdk or a browser source, change realization of all getters or something else
In browser Javascript, there is no such thing as a global variable that is not a property of the window object. So, if that's truly what you are trying to do, then it cannot be done. Yes, you might be able to create a getter on the window object with Object.defineProperty(), but that's still a property on the window object so I'm not sure how that helps you.
Likewise, there is no structure in Javascript such that:
window.ActiveXObject === undefined
and this works:
var x = new window.ActiveXObject;
Javascript just simply doesn't work that way. The property either exists or it doesn't. It can't be undefined for one way of accessing it and defined for some other way of accessing it.
You might also be able to create the property on the window object so it is not enumerable if you want it to be less visible for some reason.
If you explained what you're really trying to accomplish, there may be some work-arounds by enclosing the relevant code in a closure and defining the variable in the closure, but without knowing more details about what the actual problem to be solved is, we can't help more specifically than that.
If you just want the variable defined for YOUR code only, then you can just put it in a closure:
(function() {
var myVar = "foo";
// other parts of your code
// elsewhere in your code
console.log(myVar);
})();
Your code can treat it like a global, but it's really not a global, it's just defined within the scope that your code lives and not available to any other code outside this scope.
Theoretically, this is possible with lexically declared variables in ES6:
let variable = 5;
console.log(variable); // 5
console.log(window.variable) // undefined
However, the current let support in FF is not as advanced, and still treats this a property of the global object.
If the variable only needs to be accessible by your project code, wrap all of your project code in a self executing anonymous function.
(function(){
var internalGlobalVar = "some value";
//All your code gets wrapped in here...
})();
Then if you tried to alert(window.internalGlobalVar) you would get undefined.
We use google closure compiler with plovr and wrap all of our code in a self executing anonymous function so basically all of our global variables are project scope, not on the window "output-wrapper": "(function($){%output%})(jQuery);"

How can function references be executed properly (1)?

win points to window. NS is a temporary namespace for this post. I thought that if I wanted access to setTimeout, I could just copy over the function reference as such:
NS.setTimeout = win.setTimeout;
However, execution will throw an error:
NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object # ...
To fix this error, I just did:
NS.setTimeout = function (arg1, arg2) {
return win.setTimeout(arg1, arg2);
};
However, I don't know why this fixed it. I don't know what language mechanics are causing this behavior.
What you want is this :
NS.setTimeout = win.setTimeout.bind(win);
or what you already do, if you want to be compatible with IE8.
Because setTimeout, like many window functions, needs the receiver (this) to be window.
Another IE8 compatible solution, more elegant in my opinion than yours (because it doesn't use the fact you know the number of arguments needed by setTimeout), would be
NS.setTimeout = function(){
return win.setTimeout.apply(win, arguments);
};
The reason why you can't do that is because, when assigining, you're changeing the call context of setTimeout, which isn't allowed.
Nor is it allowed for setInterval, and many of the other native objects/functions. Again: a great rule of thumb: if you don't own the object, don't touch it. Since functions are objects in JS, that rule applies to them, too
check the specs on the global object and its properties/builtin funcitons:
There are certain built-in objects available whenever an ECMAScript program begins execution. One, the global object, is part of the lexical environment of the executing program. Others are accessible as initial properties of the global object.
And so on. But the lexical environment is quite significant. By assigning a reference to the function elsewhere, you could well be masking part of the lexical environment, or exposing too much of the global environment (eg mashups).
This fixed the problem b.c. you are changing the calling object back to the original when you call it.
return win.setTimeout(arg1, arg2);
will set the context ( or this ) back to window where it should be. The other answers are similar in the fact that they change the context to the correct value using bind to apply.

What does passing params in a jQuery plugin mean?

I've seen quite a lot of plugins which include objects like document, window, undefined into the arguments of both opening and closing.
Is this necessary?
What does it mean?
When should these be used?
;(function( $ , document, window, undefined) {
"use strict";
$.fn.pluginname= function(options) {
//Code
};
})( jQuery, document, window, undefined);
From jqueryboilerplate.com
// undefined is used here as the undefined global variable in ECMAScript 3 is
// mutable (ie. it can be changed by someone else). undefined isn't really being
// passed in so we can ensure the value of it is truly undefined. In ES5, undefined
// can no longer be modified.
// window and document are passed through as local variable rather than global
// as this (slightly) quickens the resolution process and can be more efficiently
// minified (especially when both are regularly referenced in your plugin).
Fore some extra credit, follow the link and you will see why the method signature is prefaced with a semi-colon.
Also, your example is a bit incorrect: you should not be passing in 'undefined' on the last line when you invoke the function. The reasoning is explained in the first paragraph I pasted in above.

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

This question already has answers here:
How does this JavaScript/jQuery syntax work: (function( window, undefined ) { })(window)?
(5 answers)
Closed 8 years ago.
I guess using this pattern is the new hotness, but I don't understand what the advantage is and I don't understand the scoping implications.
The pattern:
(function(window, document, undefined){
window.MyObject = {
methodA: function() { ... },
methodB: function() { ... }
};
})(window, document)
So I have several questions about this.
Is there a particular advantage to encapsulating an object like this?
Why are window and document being fed in instead of just being accessed normally?
Why the heck is undefined being passed in?
Is attaching the object we're creating directly to window a particularly good idea?
I'm used to what I'll call the Crockford style of Javascript encapsulation (because I got it off the Douglas Crockford Javascript videos).
NameSpace.MyObject = function() {
// Private methods
// These methods are available in the closure
// but are not exposed outside the object we'll be returning.
var methodA = function() { ... };
// Public methods
// We return an object that uses our private functions,
// but only exposes the interface we want to be available.
return {
methodB: function() {
var a = methodA();
},
methodC: function() { ... }
}
// Note that we're executing the function here.
}();
Is one of these patterns functionally better than the other? Is the first one an evolution of the other?
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.
I think this is mostly for code that needs to run in multiple window contexts. Say you have a complex application with lots of iframes and/or child windows. They all need to run the code in MyObject, but you only want to load it once. So you load it in whatever window/frame you choose, but you create a MyObject for each window/frame with references to the proper window and document.
Taking an undefined argument is trying to protect against the fact that undefined can be changed:
undefined = 3;
alert(undefined);
See CMS's answer about how this improves safety.

Understanding jquery source code

I have recently started to delve deeper in to JavaScript and have come across this code construct in JQuery.
(function( window, undefined ) {
})(window)
Reading on stack overflow (and elsewhere) I have come to the conclusion that this is the same as
function foo(window, undefined) {
...
}
foo(window);
Am I correct in my assumption?
If so, what are the advantages of the former? (other than confusing newbs)
There are several things you need to know to make sense of it:
It is an anonymous function, which simply means it does not have a name.
The function is called immediately after it is declared. You see the open parenthesis on line 2, immediately after the function definition? That means, "call this function".
Only one parameter is passed to the function. That parameter is "window", which is the name of the global scope inside of a browser.
The function being called actually expects *2* parameters, but we're calling it with one. Javascript lets you call functions with more or fewer parameters than the function actually expects. There are ways of getting to the list of parameters that was passed.
Since we are only passing one parameter, the second parameter will automatically be set to "undefined". "undefined" is a special javascript value that means, get ready, "undefined".
It just so happens that we have also named our second parameter with the name "undefined". So in effect, we have created a local variable (parameters are very much like local variables) that is named undefined, and whose value is undefined.
Why on Earth did we do that? It is a way of ensuring that, within our anonymous function, if we refer to "undefined", it really will have the value of "undefined". If we didn't do that, and some crazy code outside of our scope redefined "undefined" (by saying something like "undefined = 42"), then we'd write code thinking we were referring to undefined but we'd actually be referring to 42. These shenanigans with passing 1 parameter but expecting 2, and calling the second one undefined, protects us from such nonsense.
I hope that's clear, let me know if it is not. I learned all that from Paul Irish's video mentioned above.
This is an anonymous function. It is created and then goes out of scope, which here is the advantage. It is created and instantiated immediately. What is good about this is that it is not going to collide with any function on the global namespace, and thus will not obliterate anything you may have included on the page.
It is an anonymous function, it has quite a few benefits, like being only active in the current scope. You can read more about it here.

Categories

Resources