Anonymous closures and global imports - javascript

I was reading this article about the module Javascript pattern, but I don't understand what is the benefit of the "Global import".
What is the difference between:
(function () {
alert($('#theForm').attr('method'));
} ());
and
(function ($) {
alert($('#theForm').attr('method'));
} (jQuery));
Both methods has the same effect, so I think I am missing the point here.
What is the point of pass global variables as parameters in the anonymous closure? what are the benefits?

Lots of scripts (such as Prototype and Mootools) also use the $ character. It is therefore sometimes useful to not use that character on a global level. You can do this in jQuery by using jQuery.noConflict(). You then have to use jQuery to do jQuery selections and the like.
If, however, you have a section of code (a "module", perhaps) that you know will only use jQuery, you can redefine $ for that section of code only using that pattern. The object known as jQuery outside the function is now known as $ inside the function:
(function($) { // the first parameter is known as $
// inside the function, you can access jQuery by the name $
}(jQuery)); // pass jQuery as the first argument

By the second version, you are ensuring that you may use the dollar-sign $ for jquery. Otherwise, you could get into trouble, when you import a second javascript library that also uses the dollar sign as an alias (prototype for example).
So by the second version, you always ensure there will be no conflicts, by passing in the unique name (jQuery in this case).

A simplified example to explain this would be as follows.
var jqueryCloneLibrary = {libName : 'jqClone_1.1.1',size : '4kb'}; //
(function(_){console.log(_.libName,_.size)}(jqueryCloneLibrary))
Above, a clone on global level has been declared and stored as a reference in var jqueryCloneLibrary.
The reference to the object i.e jqueryCloneLibrary is passed as an argument to the IIFE (immediately invoked function)
Inside the function definition, we have the parameter defined as an _ using which we are able to access the properties _.name and _.size.
We include jquery or any other library the similar way and this is known as a Global Import.

Related

What is the use of passing global variables to functions through arguments in javascript?

I see some self executing function, where the global variable is passed as an argument, even though the global variables are accessible inside the function.
var MyApp = {};
(function(app) {
//Do something with app varaible.
})(MyApp);
is there any reason to pass them to the functions through arguments?
Function arguments, as well as variables declared with var inside the scope of the function, are scoped locally and shadow any values for the same variable in outer scopes.
In your example, this allows $ to have a value outside of the function, and it is only temporarily switched to the jQuery object while inside the function.
$ = "stuff";
console.log($); // "stuff"
(function($) {
console.log($); // the jQuery object
})(jQuery);
console.log($); // "stuff"
Considering your initial code with jQuery:
Is just to help writing code, some programmers get addicted to the $ so they pass the jQuery as arguments and call it $. That code is a better way of doing this $=jQuery, in codes where other frameworks already user $, $=jQuery would overwrite other API code... You typically see that kind of code construct when you use jQuery along with other conflicting libraries that forced you to call jQuery.noConflict().
jQuery.noConflict() removes you the $ functions where you previously were able to do this $('div')... so to keep using $ as before, in code where you know that $ should mean jQuery then you declare code like:
(function($){
...
})(jQuery);
About the closures in general:
This is useful in other cases, imagine you have huge function working using the jquery $ variable and then you add a library to your project that conflicts with $, the closure above would help you in not re-write the code, you could wrap it inside the closure an user $ inside.
Just one more thing, for clearness, (function(){})() is called a closure because you declare an anonymous function an then you execute it, which means you create a private context inside that function.
link about closures: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures
The why for passing globals as parameter to closures, is because when you pass the globals as parameters to locals you rename that global to another name inside of the closures context only. This is a controlled way of saying "hey here jQuery is called $ and jQuery".

self executing function arguments

In order to prevent prototype.js conflicts with jquery I wrapped my jquery code in the following snippet:
(function($) {
})(jQuery);
If I understood this correnctly, $ === jQuery would be true inside my function. But is the actual "in parameter" jQuery in this case, which gets the alias $ inside my function?
If my assumption is correct, do I need to pass jQuery on both places in order to call it jQuery, or would it be ok to just pass it at the end of the function?
Within your IIFE you can use either $ or jQuery - they're both in scope.
Only the (jQuery) is actually being passed as an argument - the $ is just the function parameter (and therefore aliased to jQuery).
To see that, your code is almost equivalent to:
var f = function($) {
...
};
f(jQuery);
except that your IIFE is an anonymous function.
If I understood this correnctly, $ === jQuery would be true inside my function. But is the actual "in parameter" jQuery in this case, which gets the alias $ inside my function?
Yes. $ is the parameter name, and the variable jQuery is what you pass in as an argument - it could be any expression.
If my assumption is correct, do I need to pass jQuery on both places in order to call it jQuery, or would it be ok to just pass it at the end of the function?
Yes, you would need to rename the parameter. Only it doesn't make much sense then, as you could just refer to the global jQuery variable then (unless you plan to overwrite that, e.g. with a different jQuery version) - the $ alias is only for brevity. If you want to avoid confusion with Prototype, use jQ instead.
Inside the closure, only $ reliably references the jQuery library; more specifically, the library version at that point in time.
When another version of the library is loaded afterwards, only $ still points to what you expect; the jQuery symbol would have been replaced by the latter version.
If you wish to use the jQuery alias inside the function you would need to rename $ to jQuery in the function arguments.

Self-invoking function and params?

I've seen the next way of writing self-invoking functions:
(function (app) {
app.foo = {
bar: function(){}
};
}(App));
Where App is a global object.
I wonder, why do we need to pass App as a param into a function? Why don't just use this:
(function () {
App.foo = {
bar: function(){}
};
}());
I see only one advantage of using the first way. If we for some reason rename the App object, then we can easily rename the param in brackets and our code will work as it works. But in case of the second way we will probably need to rename App in all places where we use it.
Are there other differences?
It means that the contents of the function – with regards to the app identifier – are agnostic to the global (or parent) scope.
One of the scenarios in which this is done is, for example, with jQuery, when you don't want to assume that the jQuery object is called $ (e.g. if no-conflict mode is on), but you do want to call it by that name. Passing it through an anonymous function like this (i.e. (function($) {})(jQuery)) allows you to generate a locally-scoped alias that doesn't interfere with the external meaning of the name $ in the parent/global scope.
The other answers explain the benefit of having a locally scoped copy. There are a few other benefits too:
As a micro-optimization it reduces scope lookups (it's less expensive to find a local var than a global one).
It can help in the minification process as all your params are reduce to single letter named vars.
It gives you a pseudo dependency management technique...in your example, you know your code is dependent on App.
For example, many libraries use the "$" character as a shortcut for their main function (e.g. JQuery). This is convenient, but can cause a clash when using multiple libraries. So, you could pass JQuery in like this:
(function($) {
// Code
var nav = $('#nav');
// More code
})(JQuery);
That way, you can still use the convenient shortcut, but you can also avoid clashes (as long as you also configure the libraries not to use the "$" shortcut).
You can also use it to redefine global variables locally to ensure they contain whay you expect:
(function($, undefined) { ... })(jQuery);
Where undefined is now the expected undefined. Also see: What is the purpose of passing-in undefined?
Most other uses are well covered in the other answers.

Can someone explain what function($) does in jQuery

Recently I was reading someone else's code, and came across this:
// Semicolon (;) to ensure closing of earlier scripting
// Encapsulation
// $ is assigned to jQuery
;(function($) {
// DOM Ready
$(function() {
...
});
})(jQuery);
I understand the point of the leading ;, And I understand that $(function() { is the same as document ready, but what is the point of adding function($)?
I understand it's a closure, but since this is always being called at the global scope, it seems like you don't need to bother with it. The $(function() { will use the same global object either way, no?
Is it to safeguard against something, or is it a best practice for another reason?
It's a common structure for a jQuery plugin. It safeguards against the $ identifier having been overwritten and used for something else. Inside the anonymous function, $ is always going to refer to jQuery.
Example:
$ = "oh no";
$(function() { //Big problem!
//DOM ready
});
By introducing a new scope, you can ensure that $ refers to what you expect it to:
$ = "oh no";
(function($) { //New scope, $ is redeclared and jQuery is assigned to it
$(function() { //No problem!
//DOM ready
});
}(jQuery));
The main reasoning behind this is that numerous other JavaScript libraries use $ as an identifier (e.g. PrototypeJS). If you wanted to use both Prototype and jQuery, you need to let Prototype have its $ identifier, but you probably don't want to write out jQuery every time you want to call a jQuery method. By introducing a new scope you allow jQuery to have its $ back in that execution context.
The code sample you've provided is an example of a Self-Invoking Function:
(function(){
// some code…
})();
The first set of parentheses defines a function: (an anonymous function wrapped in parentheses)
(function() {})
That defines the anonymous function. On its own, it doesn't do anything. But if you add a set of parentheses () after the definition, it's the same as the parentheses used to call a function.
Try this out:
(function(message) {
alert(message);
})("Hello World");
That creates a function which accepts a parameter, and displays an alert box containing the provided value. Then, it immediately calls that function with a parameter of "Hello World".
In your example, a self-invoking function is defined. It accepts a parameter, which is named $. Then, the function is immediately called, with a reference to jQuery being passed in as the argument.
This is common if you want jQuery to operate in noConflict() mode (which removes the global reference to $).
In noConflict() mode, you can still access jQuery via the jQuery global variable, but most people would rather use $, so this self-calling function accepts the global jQuery variable as a parameter named $ in the scope of the function, which leaves you free to use the $ shortcut within the self-invoking function while having jQuery operate in noConflict() mode to avoid clashes with other libraries that use $ in the global scope.
Hope this answers your question!

2 ways of writing jquery, what's the difference?

I have got a function, inside which are some simple expressions, adding nums, appending doms, etc.
Since I only have to call it once, so an anonymous function could do it. But which way should I choose and what's the difference?
1: Shorthand for $(document).ready() {}) I seen this a lot,
$(function(){
var something;
++something;
});
2: Found in jquery plugins. Is it binded to $(document).ready() too?
(function ($) {
var something;
++something;
})(jQuery);
The second one is not bound to the ready event.
In detail. This:
$(function(){ /* ... */ });
needs a variable $ defined. Usually this variable exists when jQuery is loaded and points to the jQuery function.
Subsequently, when you call the jQuery function with a function argument, jQuery is binding this function argument to the ready event. The above is equivalent to
jQuery(function(){ /* ... */ });
which is in turn a convenience shorthand for
jQuery(document).ready(function(){  /* ... */ });
Your second code snippet
(function ($) { /* ... */ })(jQuery);
does not rely on $ being defined or pointing to jQuery() (this can happen if multiple JS frameworks are loaded in parallel).
To still have the convenience of $ within a certain region of code, it creates a function within which $ is defined and points to jQuery(). However, it is not bound to a DOM event.
But this would be:
(function ($) {
$(function(){ /* ... */ });
})(jQuery);
This set-up is used to minimize the conflict between JS frameworks or other pieces of code that rely on $. jQuery plug-in authors use it to write plug-ins that work under many environments.
If you think the combined one is too complicated, jQuery also has a shorthand feature, which avoids variable conflicts and binds to document ready at the same time. But be careful, it only works on jQuery and has some downsides.
jQuery(function($) { /* some code that uses $ */ });
For more details, see these two articles:
Using jQuery with Other Libraries
.ready() # api.jquery.com (Aliasing the jQuery Namespace)
First
It's just shorthand
Second
You are sandboxing the use of $ to reduce conflicts with other libraries that use the $ shorthand.
$ is just a shortcut for the jQuery variable and is being passed into the inner function of the immediately invoked function...
Example
var outerVar = "something";
(function innerFunc(passedVar) {
passedVar === "something"; //true
})(outerVar);
innerFunc is executed and passed outerVar as its argument.
In your first example, the shorthand form is functionally identical to $(document).ready().
The second example is an immediately-invoked anonymous function (Thanks #Raynos for the correction: this is often called a self-invoking function; it is not one). The function is defined and executed in place, taking jQuery as its argument. One advantage of this approach is that variables declared within the function will not "pollute" the global (window) scope (as opposed, for example, to simply running that code outside the function). In your example, something is undefined outside the function.
Since jQuery is brought into the function as the argument $, $ is guaranteed to be jQuery within the body of that function -- even in cases where other libraries are using $ outside the function.
A useful side note: it's sometimes helpful to name "anonymous" functions. The, uh, functionality remains the same, but names can make it much easier to debug complex code.
(function superFunction (foo) { // naming this "superFunction"
var something = 10;
do_something_with( foo, something );
})(bar);
No it isn't, it is just a shorthand
No it isn't. This code makes sure that $ is really jQuery and not just another javascript library
From http://docs.jquery.com/Plugins/Authoring:
But wait! Where's my awesome dollar sign that I know and love? It's
still there, however to make sure that your plugin doesn't collide
with other libraries that might use the dollar sign, it's a best
practice to pass jQuery to a self executing function (closure) that
maps it to the dollar sign so it can't be overwritten by another
library in the scope of its execution.
Just combine the two styles.
jQuery(function($) {
// uses the real jQuery as $
// code
});
The first style was used to run some code when the DOM is ready.
The second style is used to ensure $ === jQuery and also to make $ a local variable (reduces lookup time by a tiny fraction)

Categories