I was researching on jQuery best practices and found this article by Greg Franko
Normally, I do:
$("document").ready(function() { // The DOM is ready! // The rest of the code goes here });
But the article recommends to use:
// IIFE - Immediately Invoked Function Expression (function($, window, document) { // The $ is now locally scoped // Listen for the jQuery ready event on the document $(function() { // The DOM is ready! }); // The rest of the code goes here! }(window.jQuery, window, document)); // The global jQuery object is passed as a parameter
I can see the comments there, but I couldn't figure out what it exactly saying.
So, which is the better approach and why?
I know that both methods will work, but how does the second one become the better?
It is in no way required. All it does is make sure that the DOM is loaded before trying to query for and use the elements inside the DOM (usually after dom is ready and before body. onload fires). You can use jquery perfectly fine without it.
There is also $(document). on( "ready", handler ) , deprecated as of jQuery 1.8 and removed in jQuery 3.0. Note that if the DOM becomes ready before this event is attached, the handler will not be executed.
jQuery ready() Method The ready event occurs when the DOM (document object model) has been loaded. Because this event occurs after the document is ready, it is a good place to have all other jQuery events and functions. Like in the example above. The ready() method specifies what happens when a ready event occurs.
ready() function will load as soon as the DOM is loaded and before the page contents are loaded. You should wrap all your javascript code with this function to ensure that the code only runs when the page is fully rendered.
Immediately Invoked Function Expressions (IIFEs)
IIFEs are an ideal solution for locally scoping global variables/properties and protecting your JavaScript codebase from outside interference (e.g. third-party libraries). If you are writing jQuery code that will be run in many different environments (e.g. jQuery plugins), then it is important to use an IIFE to locally scope jQuery because you can’t assume everyone is using the $ to alias jQuery. Here is how you would do it:
// IIFE - Immediately Invoked Function Expression (function($, window, document) { // The $ is now locally scoped // The rest of your code goes here! }(window.jQuery, window, document)); // The global jQuery object is passed as a parameter
If you don’t like having to scroll to the bottom of your source file to see what global variables/properties you are passing to your IIFE, you can do this:
// IIFE - Immediately Invoked Function Expression (function(yourcode) { // The global jQuery object is passed as a parameter yourcode(window.jQuery, window, document); }(function($, window, document) { // The rest of your code goes here! } ));
To read more about IIFEs, you can read my blog post titled, I Love My IIFE.
jQuery Ready Event
Many developers wrap all of their code inside of the jQuery ready event like this:
$("document").ready(function() { // The DOM is ready! // The rest of your code goes here! });
Or a shorter version like this:
$(function() { // The DOM is ready! // The rest of your code goes here! });
If you are doing either of the above patterns, then you should consider moving the pieces of your application (e.g. methods), that don’t depend on the DOM, outside of the ready event handler. Like this:
// IIFE - Immediately Invoked Function Expression (function(yourcode) { // The global jQuery object is passed as a parameter yourcode(window.jQuery, window, document); }(function($, window, document) { // The $ is now locally scoped $(function() { // The DOM is ready! }); // The rest of your code goes here! } ));
This pattern makes it easier to separate your logic (from a code design perspective) since not everything has to be wrapped inside of a single event handler callback function. It will also improve your application’s page load performance, since not everything needs to initialized right away. A great example of this is lazy binding DOM event handlers that do not need to be bound when the DOM is ready.
Adapted from my jQuery Best Practices blog post: http://gregfranko.com/blog/jquery-best-practices/
The only difference between your code and the "suggested" approach is compatibility and possibly better compression. There are no speed differences.
Passing window.jQuery
as the first argument to your IIFE (immediately-invoked function expression) and naming it $
within the IIFE will just allow you to use jQuery without interfering with other libraries that assign themselves to the global $
. If you don't use any other libraries that assign themselves to the global $
, the first argument to your IIFE isn't going to serve any purpose.
Passing window
and document
to your IIFE will allow JS minifiers to transform your code into something like this (without the whitespace), which gives you slightly better compression:
(function(a, b, c) { a(c).ready(function() { // ... }); })(window.jQuery, window, document);
Unless you use window
and document
extensively, I would just do:
;(function($) { $(function() { ... }); })(jQuery);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With