15

I understand that the following is shorthand for $( document ).ready():

$(function() {
    console.log( "ready!" );
});

I also understand what an anonymous JS function is, but does jQuery does anything special when it's called using one. I.e.:

(function() {
    console.log( "ready!" );
})($);

Is the latter just a normal anonymous JS function that uses jQuery (ie. it will NOT be considered shorthand for $(document).ready() and so will execute immediately)?

I feel this MUST have been asked before, but I can't find it if it has.

Chuck Le Butt
  • 47,570
  • 62
  • 203
  • 289
  • 2
    As a side note, I tend to (strongly) prefer to use `jQuery(function($) {//...$ is guaranteed to be jQuery here });` - the "no-conflict-safe" document ready. – random_user_name Jan 23 '17 at 15:19
  • 3
    The `(function() { console.log( "ready!" ); })($)` takes the parameter $ but does nothing with it. – Dominique Fortin Jan 23 '17 at 15:20
  • 2
    In second case you are passing jquery instance into anonymous function (have no idea why). It will be executed immeidiately. – degr Jan 23 '17 at 15:20
  • The latter in indeed just an anonymous function. I'm not even sure it _does_ anything. Something that you can actually find, however is `( function( $ ) {/* your code*/ })(jQuery)` which makes sure your code has `$` as jQuery (the identifier is sometimes overriden to some different library). – VLAZ Jan 23 '17 at 15:22
  • @cale_b Thanks. I know what an IIFE is, so not looking for an explanation of that. I just wanted to make sure jQuery didn't do something magical and somehow treat it differently. – Chuck Le Butt Jan 23 '17 at 15:26

3 Answers3

12

As you mentioned, the former is indeed a shorthand for $(document).ready(). As for the latter, this is just an Immediately Invoked Function Expression.

(function ($) {
    console.log('ready');
})(jQuery);

This function is simply an anonymous function which receives a parameter named $. The function is immediately invoked with some value (in this case jQuery) as the parameter.

IIFEs can also be used to isolate scopes and to avoid global variables in web applications which contain multiple JavaScript files. In this case a parameterless IIFE could be used:

(function () {
    // x is only accessible within this IIFE
    var x;
    // do something...
})();

For more information regarding Immediately Invoked Function Expression, see this question: What is the purpose of a self executing function in javascript?

Lior Erez
  • 1,852
  • 2
  • 19
  • 24
  • This is the more accurate answer *specific to jQuery*. Bonus points for using a "no-conflict-safe" model that will ensure jQuery could be run along with other libraries that use the `$` function name. – random_user_name Jan 23 '17 at 16:14
  • 1
    Great answer, but I'm more familiar with the term "Immediately Invoked Function Expression" than "Self Invoking Anonymous Function". Is there a difference? @cale_b? – Chuck Le Butt Jan 23 '17 at 16:24
  • 1
    @ChuckLeButt You're right, I've added the other term to the answer as well – Lior Erez Jan 23 '17 at 16:30
9

The first one is, indeed, a shorthand for $( document ).ready(), as pointed here.

But the second one is Immediately-Invoked Function Expression (IIFE), an anonymous function that is declared and immediately called.

In fact, the correct syntax (the argument is missing in your example) is:

(function($) {
    //my $ object is local now
})(jQuery);

In this case, you're calling the anonymous function with an argument.

The main advantage of this pattern (IIFE) is: isolate your code (you can create as many variables as you want and it'll be restricted to your anonymous function scope, unless you return something). This pattern is used a lot to define "private" and "public" methods. Like this:

var myModule = (function() {

    function privateFunction() { console.log("I can't be accessed from outside :("; }

    var privateVar = "me too :(";

    function publicFunction() { console.log("Hey! I'm here!"; }

    /* expose what you want */
    return {
        publicFunction: publicFunction
    }

})();

myModule.publicFunction(); //Hey! I'm here!
myModule.privateFunction(); //undefined;

You can also call it module pattern.

In your second example, you're calling the recently-created anonymous function with an argument, and your anonymous function receives that argument. This is a way of dependecy injection.

This way, you manipulate your global variable inside the function as local. Note that in the first example, we're passing a jQuery object and manipulating it inside your function as $. It's more difficult to someone override jQuery object, but, some script can re-assign the global dollar symbol, specially if you don't have full control of your app. This way, you're allways passing te jQuery object and manipulating it as $.

At the end, let me list some other advantages of passing parameters to a IIFE grabbed from here:

  • it's faster: JavaScript first lookup into the local scope (before climbing up). It may improve performance a bit.

  • helps minification: minifier can now rename variables inside your scope to a one letter word, reducing code size.

mrlew
  • 7,078
  • 3
  • 25
  • 28
3

Is the latter just a normal anonymous JS function that uses jQuery (ie. NOT shorthand for $(document).ready() and so will execute immediately)?

Yup, exactly, it's just a normal IIFE which takes the $ global variable as an argument

(function(dollarSignArgument) {
    console.log( "not really ready!" );
})($)

it'll be executed immediately

nicosantangelo
  • 13,216
  • 3
  • 33
  • 47