difference between function($) and $(function()) - javascript

What is the difference between function($) and $(function())?
Is this code redundant?
(function($) {
"use strict";
$(function() {
run_code();
});
})(jQuery);
Are they both document ready functions?

They may look similar, but they are completely unrelated.
This is called an Immediately Invoked Function Expression (IIFE). These are not specific to jQuery, but in this case, it ensures that within the body of this function, $ will refer to jQuery, even if something outside the function has overwritten the global $ variable with something else. It is a defensive practice for minimizing conflicts with other libraries.
An additional benefit is that any variables declared within this function will not be added to the global scope. Even without jQuery, this is a common practice used to help modularize code and avoid polluting the global scope.
(function($) {
"use strict";
})(jQuery);
This tells jQuery to execute the specified function when the DOM is "ready":
$(function() {
run_code();
});

Related

Calling function/nested function from external js file

I'm having some issues with running some functions from an external js file.
The html includes:
<script src="js/file.js"></script>
<script>
$("#center-button").click(function() {
explodePage("center");
});
</script>
The js file includes:
var explodePage = function(button) {
//code here
aboutPage();
}
var aboutPage = function() {
//code here
}
The explodePage function runs fine, but as soon as it reaches the call to the nested aboutPage function, it starts throwing these uncaught typeerrors at me. It works fine if I don't use an external js file and just put everything into the html. Pretty new to this so probably missing something obvious in scope or something. Any solutions?
Declare the function's definition as below:
function explodePage(button) {
//code here
aboutPage();
}
function aboutPage() {
//code here
}
Explanation:
When you use the var keyword for declaring functions, the execution of JS happens as when the variable is initialized, you cannot reference or use variable's before declaration. In contrast with the name function defintion JS interpreter first picks the enclosed functions before execution and initializes it before the code execution. This is called AST- Abstract syntax tree that is followed by JS interpreters.
Also Remember:
Also bind your Jquery code inside a Jquery document ready function, just to make sure the Jquery and the DOM elements are available for the bindings.
It's not a good a idea to pollute the global window object with variables, since there can be collisions. And immediately-invoked function expression is a good solution for this.
(function(){
//You can declare your functions in here, and invoke them below
$( document ).ready(function() {
//Check that the DOM is ready, in order to manipulate it an add events
$("#center-button").click(function() {
explodePage("center");
});
});
})($); //Notice that we are injecting a dependency, in this case jQuery

IIFE inside $(document).ready or the other way around

My colleague has been extensively using IIFE inside (document).ready in his code. Now, I've read this post:
JQuery best practise, using $(document).ready inside an IIFE?
This got me thinking if we should use $(document).ready inside IIFE or is it also fine the other way around as my colleague is doing.
So basically, his code is setup like this:
jQuery(function() {
(function($) {
//...
// Code here
//...
})(jQuery);
});
Is what he is doing generally fine?
Some may argue that this is a matter of style/opinion, but if you consider the typical goal of an IIFE in that context I believe the answer is yes, it is acceptable to use your alternative way, but there is a potential drawback.
Wikipedia has to say that:
Immediately-invoked function expressions can be used to avoid variable hoisting from within blocks, protect against polluting the global environment and simultaneously allow public access to methods while retaining privacy for variables defined within the function.
Neither method pollutes the global namespace, because they don't declare any variables. Therefore, it should be fine to use either way. Although note that it is partially redundant because the function handler for the ready event already creates a new scope, and also note it is the most common practice to see IIFE functions encapsulate all of the code in a file.
One drawback to the way that your colleague is using: If you did want to do some javascript logic that didn't depend on the DOM being ready, then you would not have the benefits of the IIFE if you put your code outside of the IIFE. So something such as this would not be safe:
// Non-DOM-ready-required code here (NOT scope-safe)
jQuery(function() {
(function($) {
//...
// DOM-ready-required code here
//...
})(jQuery);
});
Using the common style gives you the full IIFE benefit:
(function($) {
// Non-DOM-ready-required code here (scope-safe)
$(function() {
//...
// DOM-ready-required code here
//...
});
})(jQuery);
In my opinion, your colleague is jumping through an extra hoop for no reason. I'm going to ignore the outer $(document).ready as it's of no real consequence.
/*jQuery(*/function() {
(function($) {
//...
// Code here
//...
})(jQuery);
}/*);*/
Using an IIFE as the entire body of the callback to jQuery confers no extra benefit in scope isolation. It's the same as if the code were
/*jQuery(*/function() {
//...
// Code here
//...
});
The only thing that the IIFE has done is allow you to reference jQuery as $.
Now, if there were more substantive code inside the callback, then there could be some benefit in using an inner IIFE. In the following example, the callback contains two IIFEs,
jQuery(function() {
// IIFE
(function($) {
//...
// Code here
//...
})(jQuery);
// IIFE 2
(function($) {
//...
// Code here
//...
})(jQuery);
});
and the use of IIFE's allows scope isolation between the two blocks of code.
Back to the main question:
This got me thinking if we should use $(document).ready inside IIFE or
is it also fine the other way around as my colleague is doing.
Now, to be honest, I don't understand why either of these should be regarded as a best practice, even after looking at your link. The people who answered never explained why it should be a best practice.
Looking at
(function($) {
$(document).ready(function() {
// other code here
});
})(jQuery);
versus
//(function($) {
$(document).ready(function() {
// other code here
});
//})(jQuery);
There really isn't any significant advantage. Just as in my earlier example, the use of the IIFE offers no scope isolation advantage, and does nothing other than to allow you to reference jQuery via $.
However, in the actual linked question , the code looks like this:
(function($) {
// other code here 1
$(document).ready(function() {
// other code here 2
});
})(jQuery);
and in this case, the IIFE does serve a purpose of keeping the variables used in other code here 1 from leaking out to global scope. But this has nothing at all to do with $(document).ready(). Restructuring the code as
(function($) {
// other code here 1
})(jQuery);
jQuery(document).ready(function() {
// other code here 2
});
does the same thing.
The moral of this answer is that using an IIFE to wrap loose code that's not already inside a function gives you benefits, while wrapping code that's already inside a function doesn't give you anything (unless you count changing the reference).

Which JavaScript design pattern is this?

I'm not sure which JavaScript design pattern I'm following. Can someone please help shed some light on it?
var masonrySupport = ({
large__videos__support: function() {
$('.masonry-container .largeRec').find('.itemMasVideo').parent().addClass('item_largeRec_video_height');
},
smallRec__videos__support: function() {
$('.masonry-container .smallRec').find('.itemMasVideo').parent().addClass('item_smallRec_video_height');
},
init: function() {
this.large__videos__support(),
this.smallRec__videos__support()
}
})
masonrySupport.init();
There are two "patterns" I can see here.
Using self invoking closure to isolate scope.
(function($) {
// Code here
})(jQuery);
Helps mitigate the creation of accidental global variables.
(Kind) the module pattern, where you create an object with a bunch of methods on it, and call init(). I prefer to self invoking closure version of it. The Revealing Module Pattern.
The pattern you are using is called the Module Pattern, and it is one of the most important patterns in JavaScript. You outer wrapper creates an anonymous scope that provides privacy and state to the code that you place inside it.
(function($) {
// Everything in here is private and stateful
// and we can access jQuery through the imported $ variable
})(jQuery);
To your scope, you're also passing the global jQuery object. This method is called global import, and is faster and clearer than accessing the implied global from within your scope.
Inside your scope, you are creating an API that is accessible through the masonrySupport variable, making it a Revealing Module Pattern.
I don't see this as a design pattern in the strict sense of terminology. May be associated with the module pattern, but it needs to return something to be accessible outside of it's inner scope. It's only a self executing function invoked inside a scope which in this case is jQuery. This is used in many jquery plugins. You isolate the scope of the self executing function to a specific - lets say - domain.
This can be found on the first declaration:
(function($) {
...
})(jQuery);
By closuring the function you are guarding the functions and variables declared inside the scope to a specific domain, in this way eliminating the possibility to accidentally override or redeclare some function or variable declared in the global scope. It's a common practice to isolate the scope from the global object which in Javascript world is the Object or on DOM context is window.
And it continues with the self executing function:
$(function() {
...
})
Effectively what is being done here is, once the document loads, execute two functions - 'large__videos__support' and 'smallRec__videos__support.'
Let's understand how it is being achieved,
Firstly it is Immediately-Invoked Function Expression (IIFE) in action. This pattern is often used when trying to avoid polluting the global namespace, because all the variables used in the function are not visible outside its scope.
(function($) {
...
})(jQuery);
Short hand of $( document ).ready() is being used. More here.
$(function() {
...
});
Thirdly, you are initializing one object being referenced by 'masonrySupport' and calling its method 'init.'
In JS, this is called and Immediately Invoked Function Expression (IIFE), and is known as the module pattern.
However in jQuery this pattern is used to create jQuery Plugins. I advise you to follow the best practices to make it work.
Check that jsfiddle to get you started.
Below the JS part:
(function( $ ) {
$.fn.masonrySupport = function( option ) {
if ( option === "large") {
this.find('div.itemMasVideo').parent().addClass('item_largeRec_video_height');
}
if ( option === "small" ) {
this.find('div.itemMasVideo').parent().addClass('item_smallRec_video_height');
}
return this;
};
}( jQuery ));
$( 'div.masonry-container.largeRec' ).masonrySupport( "large" );

Where should I put functions in Javascript code?

I have the following code:
(function($) {
"use strict";
$(function() {
// jQuery code here, eg:
$('body').css('padding-top', $('.nav').height());
// I want to call that func here...
});
}(jQuery));
And custom function:
function xyz(a,b) {
// do something with "a" and "b"
}
Where should I place my custom function? Before (function($) {, before $(function() {, or inside $(function() {});?
The difference is the scope.
Location : Scope
----------------------+--------------------------------------------------------
before (function($) { : in global scope, easy to call & modify from everywhere
before $(function() { : in "source module" scope / jQuery closure
inside $(function() { : in "$(function" scope
So that choice gives you the means to organize the access to your code.
In most cases you want to hide stuff to prevent unintended interactions, but in some cases (e.g. log function), you want to have access from everywhere in your web application.
If you do not need to call xyz() from outside $(function, keep it inside. If you do just need to call it within the module, keep it inside ( .. (jQuery)). If you need to call it from everywhere keep it outside in global scope.
Since you want to call the function inside the ready handler, declare it inside it
jQuery(function ($) {
"use strict";
// jQuery code here, eg:
$('body').css('padding-top', $('.nav').height());
// I want to call that func here...
xyz();
function xyz(a, b) {
// do something with "a" and "b"
}
});
But if you want to access xyz from outside the scope of the dom ready handler you will have to declare it outside the scope of the dom ready handler. Now the method is local to the dom ready handler and thus accessible only inside it.
Also as shown above you can shorten the use of IIFE and dom ready handler as shown above

Is this a double document ready?

I'm working with a script and have found the following, which I really can't find any info of what it means
(function($) {
$(document).ready(function(e) {
... bla bla bla ...
});
}) (jQuery);
Is (function($){}) (jQuery); the same as $(function () {}); ? and if so, why would somebody define twice document.ready ?
No, it's not the same. It's an anonymous function which is being passed the jQuery object, to insure that it is available as the local variable $ within the scope of the function, even if the global variable $ is overwritten by another library. It is completely different than $(function () { }) and $(document).ready(function () { }).
This particular pattern is recommended in the jQuery plugin authoring documentation:
[When authoring a plugin] it's a best practice to pass jQuery to an IIFE (Immediately Invoked Function Expression) that maps it to the dollar sign so it can't be overwritten by another library in the scope of its execution.
(function( $ ) {
$.fn.myPlugin = function() {
// Do your awesome plugin stuff here
};
})( jQuery );
Is (function($){}) (jQuery); the same as $(function () {}); ?
No. The first is immediate invocation of an anonymous function, used primarily for preventing pollution of the global scope. In this case, it's also used to make sure that $ is a reference to jQuery, without worrying about overwriting $ elsewhere.
The second is the shorthand for binding a document ready handler with jQuery.
More reading:
What is the purpose of a self executing function in javascript?
What is the reason for this JavaScript immediate invocation pattern?
No it isn't, (function($){}) (jQuery); is an IIFE(Immediately invoked function expression) passing jQuery as a parameter and using $ to represent it in the function scope so that no conflicts will occur if another library that uses $ is loaded without using jQuery.noConflict.
Nope
(function(){})();
is executed as soon as the browser encounters that script.
.ready() is an event that is triggered after the entire document is parsed
No it's not. It is a closure with a document ready handler inside it. It is used to ensure that the $ within the enclosure is reserved for jQuery and does not interfere with any other library.
A nice clear explanation here;
http://jquery-howto.blogspot.com/2008/12/what-heck-is-function-jquery.html

Categories

Resources