The purpose of that is that it's creating a modularized IIFE (Immediately Invoked Function Expression). This is useful to avoid polluting/assigning variables to the global namespace and helps prevent conflicts with other external plugins/dependencies that might appear in your app.
Yes. In the first your scripts are loaded in the head whereas your scripts are loaded in before the closing of the body in #2. It's recommend to load your scripts before the closing of the body so your page doesn't hang as it loads in your javascript files.
Go with #3 over #2. As to why, refer to point #1.
Update
Here's an example of how things would look if you were to simply assign a variable within the global namespace.
var exampleGlobal = "I'm an example global variable";
function one() {
exampleGlobal = 1;
}
....
function two() {
exampleGlobal.charAt(0);
}
one(); // Changes the exampleGlobal to a Number
two(); // Tries to use a string-based instance method but throws an error since exampleGlobal is now a number
Here we see that the exampleGlobal
is exposed and available to all functions within this script. In this case it's very easy to err and change the value/purpose of this variable anywhere in your script. Here's where IIFE's come into play:
var exampleModule = (function() {
var privatized = "I'm only accessible within this module";
return {
privatized: privatized
}
}());
In the above we're creating just but one global variable that serves as a module and encapsulates values/functions that would only pertain exclusively to it. Try accessing privatized globally. You'll find that it returns undefined as it's not available within the global scope unless you explicitly invoke the module and it's return value:
var exampleModule = (function() {...}());
console.log(privatized); // undefined
console.log(exampleModule.privatized); // returns: "I'm only accessible within this module"
IIFE's are also advantageous in the fact that you can safely avoid naming conflicts that may occur within your app. As an example, jQuery and Mootools share the $
character to invoke their respective function calls. If you'd like to safely use the jQuery without any conflicts with Mootools you pass the $
object as an argument into your IIFE, which will then shield it from the global scope.
(function($) { // Here this is just the parameter we'd like to refer jQuery as
$('div');
}(jQuery)); // You pass in the actual jQuery object here which is when/where the function is immediately invoked.