29

I am studying Backbone and the todo example apps from http://todomvc.com/ I have noticed there are 3 severals ways of starting the code in the files:

$(function() {
 // code here
});

$(function( $ ) {
 // code here
});

(function() {
 // code here
}());

I do not understand the differences and when I should use one over the other.

I also saw some people using this to start their code:

$(document).ready(function(){
  // code here
});

From what I have seen, this is the full way of writing it right?

In a more general way, should I always include my javascript code into something like that in each files?

Thanks for your advice.

Michael
  • 8,357
  • 20
  • 58
  • 86

3 Answers3

55
  1. $(document).ready(function(){}) ensures that your code runs on DOM ready, so that you have access to the DOM. You can read more about this in jQuery's documentation.

  2. $(function(){}) is just an alias to #1. Any code in here will wait for DOM ready (see the docs).

  3. $(function($){}) is equivalent to #1 and #2, only you get a clean reference to jQuery in the local scope (see the note below). You can likewise pass in $ to the function in #1, and it'll do the same thing (create a local reference to jQuery).

  4. (function(){}()) is just a self-executing-anonymous-function, used to create a new closure.

Please note that none of these are specific to Backbone. The first 3 are specific to jQuery, while #4 is just vanilla JavaScript.


Note: To understand what's going on in #3 above, remember that $ is an alias to jQuery. However, jQuery is not the only library that uses the $ variable. Since the $ might be overwritten by someone else, you want to ensure that within your scope, $ will always reference jQuery - hence the $ argument.


In the end, it basically boils down to the following 2 options:

  1. If your JavaScript is loaded in the head, you have to wait for document ready, so use this:

    jQuery(function($) {
        // Your code goes here.
        // Use the $ in peace...
    });
    
  2. If you load your JavaScript at the bottom of your document (before the closing body tag - which you should definitely be doing), then there's no need to wait for document ready (since the DOM is already constructed by the time the parser gets to your script), and a SEAF (A.K.A. IIFE) will suffice:

    (function($) {
        // Use the $ in peace...
    }(jQuery));
    

P.S. For a good understanding of Closures and Scope, see JS101: A Brief Lesson on Scope.

Community
  • 1
  • 1
Joseph Silber
  • 214,931
  • 59
  • 362
  • 292
  • 1
    Just to avoid confusion (and rage in some) self-executing-anonymous-function don't really execute themselves.. they have been coined this but are really [Immediately Invoked Functions](http://benalman.com/news/2010/11/immediately-invoked-function-expression/). **and** after posting this I *Immediately* saw the little footnote about (A.K.A IIFE) so nvm :P It is funny how we both linked to the same article though. – rlemon Aug 17 '12 at 20:27
  • 1
    @rlemon - While I agree with Cowboy (Ben Alman) that **immediatly-invoked-function-expression** is the more accurate term, **self-executing-anonymous-function** has become the standard way to refer to them. We both linked to the same article because that is the source for the **IIFE** name. P.S. That article is worth a read regardless of what you call 'em. It has some great info on these function expressions. – Joseph Silber Aug 17 '12 at 20:35
  • Ohh I've already read it, and I personally do not care what we call them, so long as people know how they function and why to use them. I just was doing my due diligence and linking it :P but It was all for not :P you already had :) I like IIFE only because it is more accurate and SEAF is a ugly acronym. – rlemon Aug 17 '12 at 20:40
  • 1
    @rlemon - I wouldn't say that SEAF is an ugly acronym. But when it comes to their pronunciation... Come on! Nothing beats "iffy" :P – Joseph Silber Aug 17 '12 at 20:42
  • @JosephSilber: Do you realize that your use of a numbered list containing references by number makes this confusing to read? You say `2. ... is just an alias to #1.` and `3. ... is equivalent to #2 ...` This makes it look like `$(document).ready(function(){})` and `$(function(){})` and `$(function($){})` are all kinda the same. If some of those numbers refer to the un-numbered examples in the OP's question then your answer will surely benefit from a bit of clarification. - **OR** it could be that I'm the confused one! Either way I'm sure it can be clarified to rule out the wrong interpretation – hippietrail Aug 17 '12 at 20:47
  • @hippietrail - Those 3 *are* all kinda the same. I don't see what would make any of this confusing. The only thing I can think of is that the order is different than in the original question, but I had to switch them around in order to explain it properly. – Joseph Silber Aug 17 '12 at 20:51
  • @JosephSilber: Actually I had no idea that `$(function(){})` implied waiting for document ready! So I thought there must've been another way to read your answer. I'm not sure if I'm the only one so dumb ... – hippietrail Aug 17 '12 at 20:55
  • @hippietrail - [Read the docs](http://api.jquery.com/ready/) (linked to in the answer). Search for "All three of the following syntaxes are equivalent". I updated my answer a bit. Let me know if that helps. – Joseph Silber Aug 17 '12 at 21:10
  • Thanks @JosephSilber now it's clear even to us dummies! (-: And thanks also for the jQuery documentation link that says so too. – hippietrail Aug 17 '12 at 21:30
18

I guess it makes sense to start out, by realizing that $ = jQuery. The purpose of which down below when reading about namespaces within anonymous functions will make more sense. But in essence, you can use either of them. One would use jQuery() instead of $() if they were using multiple libraries, and wanted the $ to be used by the other one.

$(document).ready(function(){
    // Here we have jQuery(document) firing off the ready event
    // which executes once the DOM has been created in 
    // order to ensure that elements you are trying to manipulate exist.
});

​$(function () {
    // Short-hand version of $(document).ready(function () { });
});

More information on Document.ready()

Putting the $ within the parenthesis ensures the jQuery $ alias (you can be safe it always signifies jQuery this way).

$(function ($) { /* code here : $ always means jQuery now */ }); 

Lastly you have an IIFE (Immidiately-Invoked Function Expression) - IIFE explanation

(function (myNameSpace, $) {
    // This is an anonymous function - it is ran instantly
    // Usually used for namespaces / etc
    // This creates a scope/wrapper/closure around everything inside of it
}(window.myNameSpace, jQuery));

The $ at the top (with it's matching jQuery on the bottom) signify that the $ (dollar sign) stands for jQuery within the scope of the namepsace. This is done to ensure that other libraries do not collide with what the developer intends/wants the $ to be used with.

(function (myNameSpace, $) {
    // Now because of all of this scope/wrapper/closure awesome...
    // you can create -INTERNAL- variables (sort of like Private variables from other langs) 
    // this variable cannot be accessed outside the namespace unless it is returned / exposed

    var internalVariable = '123'; // Internal

    // Even Internal functions!
    function privateFunction () {
        console.log('this is private!');
    }

    // --------------------------------------------------------
    // Public -method- of nameSpace exposing a private variable
    // Notice we're using the myNameSpace object we exposed at the top/bottom

    myNameSpace.nameSpaceMethod = function () {
        privateFunction(); // we can call the private function only inside of the namespace
        return internalVariable; // now we could get this variable
    };
}(window.myNameSpace, jQuery)); // notice these mirror the above arguments in the anon function

More information on anonymous functions

Now if we're outside of the namespace, we can see how these internal/public methods and variables are effected:

// This will come up undefined
alert(internalVariable);

// This will trigger a -method- of the myNameSpace namespace - and alert "123"
// Showcasing how we access a Public method - which itself has access to the internal variable
// and exposes it to us!
alert(myNameSpace.nameSpaceMethod());
​
Mark Pieszak - Trilon.io
  • 61,391
  • 14
  • 82
  • 96
2

These two:

$(function() {
 // code here
});

$(document).ready(function(){
  // code here
});

Are directly equivalent, they are both the way to start some jQuery when the document has loaded. The former is just a shorter version of the latter.

This one:

(function() {
 // code here
}());

is just a scoped function with zero parameters, which is immediately called with zero parameters.

Jamiec
  • 133,658
  • 13
  • 134
  • 193