Module pattern that passes jQuery or different global - javascript

Is this pattern :
// Global module
var myModule = (function ( jQ, _ ) {
function privateMethod1(){
jQ(".container").html("test");
}
function privateMethod2(){
console.log( _.min([10, 5, 100, 2, 1000]) );
}
return{
publicMethod: function(){
privateMethod1();
}
};
// Pull in jQuery and Underscore
}( jQuery, _ ));
myModule.publicMethod();
I don't understand what is the purpose of passing global, if it is anyway global ?
Is this more efficient to have jQuery or other global "closer" not so far away in prototype chain ?
And if someone wants to use
jQ
That refers to jQuery
Why just don't do
var jQ = jQuery
In scope he/she wants to use it.

One reason to do this would be if you have multiple versions of jQuery on a page using jQuery noconflict, you could isolate this code from having to know about that or worry about it. You would just pass the correct version. If you want to use the $ shorthand, this could also be good to prevent conflict with other librarys such as Mootools that also use the $ symbol.
In general though I agree with you that it doesn't seem especially useful.
Update
That does in fact seem to be the reason for this particular useage. From the source you linked:
Here, we’ve wrapped our plugin logic in an anonymous function. To ensure that our use of the $ sign as a shorthand creates no conflicts between jQuery and other JavaScript libraries, we simply pass it to this closure, which maps it to the dollar sign.
and also
This variation of the pattern demonstrates how globals (e.g jQuery, Underscore) can be passed in as arguments to our module's anonymous function. This effectively allows us to import them and locally alias them as we wish.
So its used as a contrived example to show that you can alias globals if you prefer a shorter name.

Related

What is the difference between (function(){/*.....*/})(); and (function($){/*.....*/})(jQuery);

Is there difference between :
(function() {
/*..........*/
})();
and :
(function($) {
/*..........*/
})(jQuery);
Other people explained what the difference is, but not why you use the latter.
The $ variable is most often used by jQuery. If you have one script tag that loads jQuery and another that loads your code, it's perfectly fine. Now throw prototype.js into the mix. If you load prototype.js and then jQuery, $ will still be jQuery. Do it the other way around and now $ is prototype.js.
If you tried to use $ on such a page, you'd likely get errors or weird behavior.
There are many questions on StackOverflow about this problem. Plugins shouldn't assume much about the page they're loaded in, so they use this pattern defensively.
i am asking if there is difference between (function(){/…/})(); and (function($){/…/})(jQuery);
A little difference. In case of (function($){/*…*/})(jQuery); and absense of jQuery you'll get an error message immeditally after page loads. It's a simpler to detect jquery absense or incorrect order of scripts inclusion, when jquery-based code included before jQuery.
In case of (function(){/*…*/})(); you'll get an error message when code inside this construction actually call one of jQuery methods. It's harder to detect this error, but on the other side you can include your jquery-based scripts before jquery.
I prefer first case.
The second form, (function($){/*…*/})(jQuery); can be slightly safer when working in an environment where you don't (or can't) strictly enforce what code gets put on your site.
I used to work on a large site with a lot of third-party ads. These ads would often unsafely inject their own version of jQuery and occasionally they would override jQuery's global $ object. So, depending on how we wrote our code, we might be calling methods that no longer existed or had slightly different behaviour from what we expected. This could be impossible to debug, since some ads would never appear in our area or were excluded from our environment. This meant we had to be extremely protective of scope, inject our dependencies before any ad code had a chance to load, namespace anything that had to be global and pray no ad screwed with us.
Other answers are quite fragmented so I'd like to give a more detailed answer for the question.
The main question can be self-answered if you understand..
What does (function(argument){ /*...*/ })(value); mean?
It's a quick hand version of:
var tempFunction = function(argument){
/* ... */
}
tempFunction(value);
Without having to go through the hassle of conjuring up a new terrible name for a function that you will only call once and forget. Such functions are called anonymous functions since they aren't given a name.
So (function(){/*...*/})() is creating a function that accept no argument and execute it immediately, while (function($){/*...*/})(jQuery) is creating a function that accept one argument named $, and give it the value of jQuery.
Now that we know what the expression means, surely the first think on our mind is
"Why?". Isn't $ jQuery already?
Well, not exactly. We can never be sure. $ is an alias of jQuery, but other libraries can also use the same alias. As user #FakeRainBrigand already pointed out in his answer, prototype.js also use $ as its alias. In such cases, whichever library assigns its value to $ later wins out.
The practice of (function($){...})(jQuery) is very similar to an alias import in other programing languages. You are explicitly telling the system that your function:
Requires an object/library named jQuery, and
Within your function, $ means jQuery.
So even when someone include a new library later that override the alias $ at the global level, your plugin/framework still works as intended.
Because javascript is so... "flexible" in variable assignment, some people (including me) go as far as doing things like
var myApplication = (function($, undefined){ ... })(jQuery);
Apply the same understanding, it is easy to interpret the second argument part as: assign nothing to the variable undefined. So we can be sure that even if some idiot assigned a value to undefined later, our if(checkVariable === undefined){} won't break. (it's not a myth, people really do assign values to undefined)
When is it commonly used in javascript?
This anonymous function practice is most commonly found in the process of providing encapsulation for your plugin/library.
For example:
var jQuery = (function(){
var publicFunction = function(){ /* ... */}
var privateFunction = function(){ /* ... */}
return {
publicFunction : publicFunction
}
})();
With this, only jQuery.publicFunction() is exposed at the global scope, and privateFunction() remains private.
But of course, it is also used any time you simply want to create a function, call it immediately, and throw it away. (For example as a callback for an asynchronous function)
For the bonus question
why they used (function(){}() twice in the below code?
Well, most likely because they don't know what they're doing. I can't think of any reason to put nested function in like that. None at all.
(function(){/*...*/})(); does not set $ as reference to jQuery within IIFE and (function($){/*...*/})(jQuery); sets $ or other parameter name; e.g.; (function(Z){/*...* Z("body") where Z : jQuery*/})(jQuery); as reference to jQuery within IIFE
The they are both closures. The first is just an anonymous function that will fire any well formatted code that is inside immediately. The second is the jQuery closure. It is how the jQuery library initiates it wraps its code in the JQuery object and exposes it isn't the $ symbol.
(function(){}()) // this is a closure
(function($){}(jQuery)) // is a closure that wraps the executed code inside of the jQuery returned object and exposes it via the $.
With this (function(){/*…*/})();, you are not passing any argument to the inner function, while with this (function($){/*…*/})(jQuery); you are passing jQuery as argument to the inner function and expecting its value as $(which means, you will be able to use jQuery inside the inner function).
Ex:
(function($){
$(document).ready(function() {
console.log('all resources loaded');
})
})(jQuery);
They both are examples of Immediately Invoked Function Expression. In that sense, there is no difference between (function(){/*…*/})(); and (function($){/*…*/})(jQuery);. So no benefits are gained by wrapping (function($){/*…*/})(jQuery); inside (function(){/*…*/})();
A new execution context is created when a function is executed. So when (function(){/*…*/})(); is executed a context is created. Again when (function($){/*…*/})(jQuery); is executed, another context is created. Since the first context is not used (i.e. no variables are declared inside it), I don't see any advantages gained by the wrapping.
(function() { // <-- execution context which is not used
(function($) { // <-- another execution context
"use strict";
/*..........*/
})(jQuery);
})();

jQuery variable shadowing

There is strange pattern in jQuery:
var jQuery = (function() {
// Define a local copy of jQuery
var jQuery = function( selector, context ) {
...
return jQuery;
})();
What is the practical reason for this? Why not just expose the inner jQuery function? Is it only for name clashes in the inner jQuery and outer jQuery since both are in closures.
jQuery.noConflict(true) removes the global name for jQuery. However, it would be impossible to program the rest of the jQuery library without using some name for the object, so a local, non-exposed name needs to be used. For convenience, they redefine jQuery as a variable in the scope of the anonymous function.
The pattern itself is called module pattern. It´s not specific for jQuery and it´s not strange but very helpful. It allows for hiding of the objects state and implementation. It also allows for priveleged methods (public methods with access to private data) and other good design principles.

function call with '$' as parameter

I have a script which contains the following piece of code:
(function ($) {
// ...
})($);
Can anyone explain how to read it?
Create an anonymous function
Let it take one argument which will be called $
Call the function immediately
Pass it one argument which is whatever the value of $ is in the outer scope.
If the $ in the outer scope changes (by having a new value assign to it) then the value for $ in the inner scope will be protected from the change (since it is a different variable).
This also provides a clean scope for all other variables declared inside the function (if they use var as they should).
'$' is a legal variable in JavaScript. It could have just as easily been someCrazyLongVariableName
It kind of defeats the purpose of encapsulating the $ sign into an anonymous function.
It's a self executing anonymous function that takes $ as argument.
In most of the cases, you use this markup to avoid js libraries collisions : say that you want to use jQuery and prototype in your project. Very nice, but they both use the '$' sign... how to overcome this?
// jquery code here
(function($){
alert($ === jQuery);// the $ is a shortcut to jQuery
})(jQuery);
// non-jquery code here - ex: prototype
alert($ === jQuery);// the $ is NOT a shortcut to jQuery ANYMORE
If you're not thinking about the $ in particular, the extract is creating a javascript function and calling it in a single statement.
I'm not 100% sure, but i guess that the 2 $ variables would be a different scope.
I found this page useful, if a little verbose: -
http://www.authenticsociety.com/blog/JavaScript_DollarSign
In summary, it's no different to calling the variable a, but should be avoided.

I'd like to understand the jQuery plugin syntax

The jQuery site lists the basic plugin syntax for jQuery as this:
(function( $ ){
$.fn.myPlugin = function() {
// there's no need to do $(this) because
// "this" is already a jquery object
// $(this) would be the same as $($('#element'));
this.fadeIn('normal', function(){
// the this keyword is a DOM element
});
};
})( jQuery );
I'd just like to understand what is going on there from Javascript's point of view, because it doesn't look like it follows any syntax I've seen JS do before. So here's my list of questions:
If you replace function($)... with a variable, say "the_function", the syntax looks like this:
(the_function)( jQuery );
What is "( jQuery );" doing? Are the parenthesis around the_function really necessary? Why are they there? Is there another piece of code you can give that is similar?
It begins with function( $ ). So it's creating a function, that as far as I can tell will never be run, with the parameter of $, which is already defined? What is going on there?
Thanks for the help!
function(x){
x...
}
is just a function without a name, that takes one argument, "x", and does things with x.
Instead of 'x', which is a common variable name, you can use $, which is a less common variable name, but still legal.
function($){
$...
}
I'll put it in parentheses to make sure it parses as an expression:
(function($){
$....
})
To call a function, you put () after it with a list of arguments. For example, if we wanted to call this function passing in 3 for the value of $ we would do this:
(function($){
$...
})(3);
Just for kicks, let's call this function and pass in jQuery as a variable:
(function($){
$....
})(jQuery);
This creates a new function that takes one argument and then calls that function, passing in jQuery as the value.
WHY?
Because writing jQuery every time you want to do something with jQuery is tedious.
WHY NOT JUST WRITE $ = jQuery?
Because someone else might have defined $ to mean something else. This guarantees that any other meanings of $ are shadowed by this one.
(function( $ ){
})( jQuery );
That is self-executing anonymous function that uses $ in argument so that you can use it ($) instead of jQuery inside that function and without the fear of conflicting with other libraries because in other libraries too $ has special meaning. That pattern is especially useful when writing jQuery plugins.
You can write any character there instead of $ too:
(function(j){
// can do something like
j.fn.function_name = function(x){};
})(jQuery);
Here j will automatically catch up jQuery specified at the end (jQuery). Or you can leave out the argument completely but then you will have to use jQuery keyword all around instead of $ with no fear of collision still. So $ is wrapped in the argument for short-hand so that you can write $ instead of jQuery all around inside that function.
If you even look at the source code of jQuery, you will see that everything is wrapped in between:
(function( window, undefined ) {
// jQuery code
})(window);
That is as can be seen also a self-executing anonymous function with arguments. A window (and undefined) argument is created and is mapped with global window object at the bottom (window). This is popular pattern these days and has little speed gain because here window is will be looked into from the argument rather than global window object which is mapped below.
The $.fn is jQuery's object where you create your new function (which is also an object) or the plugin itself so that jQuery wraps your plugin in its $.fn object and make it available.
Interestingly, I had answered similar question here:
JavaScript / jQuery closure function syntax
You can also check out this article to know more about self-executing functions that I had written:
Javascript Self-executing Functions
The basic plugin syntax allows you to use $ to refer to jQuery in the body of your plugin, regardless of the identify of $ at the time the plugin is loaded. This prevents naming conflicts with other libraries, most notably Prototype.
The syntax defines a function that accepts a parameter known as $ so you can refer to it as $ in the function body, and then immediately invokes that function, putting jQuery in as the argument.
This also helps not pollute the global namespace (so declaring var myvar = 123; in your plugin body won't suddenly define window.myvar), but the main ostensible purpose is to allow you to use $ where $ may have since been redefined.
You're dealing with a self-invoking anonymous function there. It's like "best practice" to wrap a jQuery plugin within such a function to make sure, that the $ sign is bound to the jQuery object.
Example:
(function(foo) {
alert(foo);
}('BAR'));
This would alert BAR when put into a <script> block. The parameter BAR is passed to the function which calls itself.
The same principle is happening in your code, the jQuery object is passed to the function, so $ will refer to the jQuery object for sure.
The jQuery at the end passes itself (jQuery) over to the function, so that you can use the $ symbol within your plugin. You ccould also do
(function(foo){
foo.fn.myPlugin = function() {
this.fadeIn('normal', function(){
});
};
})( jQuery );
To find a clear explanation of this and other modern javascript tricks and common practices, I recommend reading Javascript Garden.
http://bonsaiden.github.com/JavaScript-Garden/
It's especially useful, because many of these patterns are widely used in many libraries but not really explained.
The other answers here are great, but there is one important point that hasn't been addressed. You say:
So it's creating a function, that as far as I can tell will never be run, with the parameter of $, which is already defined?
There is no guarantee that the global variable $ is available. By default, jQuery creates two variables in the global scope: $ and jQuery (where the two are aliases for the same object). However, jQuery can also be run in noConflict mode:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
jQuery.noConflict();
</script>
When you call jQuery.noConflict(), the global variable $ is set back to whatever it was before the jQuery library was included. This allows jQuery to be used with other Javascript libraries that also use $ as a global variable.
If you wrote a plugin that relied on $ being an alias for jQuery, then your plugin would not work for users running in noConflict mode.
As others have already explained, the code you posted creates an anonymous function that is called immediately. The global variable jQuery is then passed in to this anonymous function, which is safely aliased as the local variable $ within the function.

a simple question on jquery closure

what does this mean?
(function($){
})(jQuery);
to make the question clearer, what does wrapping a function in parenthesis mean in JS (sorry, I'm a bit confused on the concept of closures). What about the $ parameter? and the "jQuery" in the end parenthesis?
Can I do the same with mootools and combine them in 1 JS file?
(function($){})(jQuery);
(function($){})(mooTools);
I have only worked with jquery and am planning to work with Mootools
Wrapping a function between parenthesis ensures this function to be evaluated as a function expression.
That happens because the Grouping Operator (the parentheses), can only evaluate expressions.
If no parenthesis are used, it will be interpreted as a function declaration, and it will cause a syntax error, since the function name is not optional for function declarations.
(function(arg){
alert(arg); // alerts test
})("test");
In the above example, the function expression is automatically executed, passing an argument.
That pattern is heavily used by jQuery plugins, since jQuery can run in noConflict mode, the $ global variable will not be created, so the jQuery global object is passed as an argument of this anonymous function and inside of that function, you can freely refer to it as $ (the received argument).
Keep in mind that also, the function context (the this keyword) inside self-executing function expressions invoked like the above example, will refer always to the Global object.
For a more in-depth info about the differences between function expressions and function declarations, give a look to the following resources:
Explain JavaScript’s encapsulated anonymous function syntax
Named function expressions demystified
CMS have given you the correct answer but I just want to add that this is not a closure. This is just the () operator being used to return the result of an expression which in this case is a function expression and the fact that in javascript, a returned anonymous function can be called directly. So this is simply combining both:
var x = (1+1); // <-- () evaluates an expression
and:
var arr = [0,1,2];
arr.push(function(text){alert(text)});
arr[3]('hello'); // <-- function returned by array called directly
And as for the $ parameter, that's just one of the characters that javascript allows for variable names. Your examples is exactly equivalent to:
(function(jQ){})(jQuery);
(function(moo){})(mooTools);
The main point for doing this is so that objects created within the function's expression can be utilized from properties and methods attached to passed in objects, without exposing those objects publicly. This can aid in preventing variable collisions. It also allows for variables created to be accessed as private storage for anything that is attached..
(function($){
//jQuery is available here as $
var myPrivateArray = []; //this is private
$.addItem = function(item) {
myPrivateArray.push(item);
}
})(jQuery);
//I can't access myPrivateArray here...
//but I can use jQuery.addItem to add something.
Here is an article on closures: http://www.jibbering.com/faq/faq_notes/closures.html
Basically, as CMS has said, it is a function expression. There is a perfect example to help you better understand about 2/3 of the way down that page.
The jQuery in the last set of parentheses means you're passing the jQuery object to the inner function. That inner function takes the object and it is assigned as $. So, when you're accessing the $ inside the function, you're actually acting upon the jQuery object you've passed.
As for mixing these with jQuery and Mootools, I've never used Mootools so I'm not sure how it assigns itself. The only thing I would think is that if it uses $ like jQuery, you can call jQuery.noConflict(); and reassign jQuery to another variable, maybe var $j = jQuery; Then, you can use Mootools as you normally would.
function($) { ... } creates a function that accepts a parameter called $.
Wrapping in in parentheses does nothing.
Adding (jQuery) calls the function with jQuery as a parameter.
This is done to make the function independent of $ in the global scope.
When you write $ in the function, you're referring to the parameter $, not the global variable $.
the mootools equivalent for namespacing $ is:
(function($) {
// $ is the mootools one (aliasing document.id)
})(document.id);
you can combine them into one file, but keep in mind that mootools is a prototypical framework and $ only serves the purpose of a selector whereas all functions go into the element/array/class etc prototypes. hence doing this in mootools works:
var foo = $("bar");
foo.hide(); // the element inherits .hide()
but in jquery it will fail and needs to be transcribed as
var foo = $("#bar");
$(foo).hide();
the point is, you can't namespace the stuff that mootools exports into prototypes.

Categories

Resources