In JavaScript, functions create new scope. Using a function wrapper around the entire contents of your JavaScript will ensure you never pollute the global scope.
For instance, if you have an HTML file with some JavaScript at the bottom:
<script>
var test = 'hello';
alert(test); //'hello'
alert(window.test); //'hello'
</script>
As you can see, the test
variable actually becomes a property of the window
object (window.test
), which is essentially JavaScript's global scope. There are many reasons you don't want to set variables on window
, particularly future compatibility problems (what if a later version of ECMAScript defines a test
property for window
?). Also, using global variables all the time is slow, because the interpreter will need to trek all the way up the scope chain whenever you use test
.
The following is functionally identical to the above, without polluting the global scope. It declares an anonymous function using function()
, then invokes it immediately with no arguments using ()
. This is usually called an immediately-invoked function expression or IIFE:
<script>
(function() {
var test = 'hello';
alert(test); //'hello'
alert(window.test); //undefined
}());
</script>
Note that this is just a normal anonymous function like any anonymous function. The set of parens after the closing curly brace invoke the anonymous function. The parens around the entire thing tell the interpreter that it's looking at a value, or expression, rather than a function declaration. This value is simply the result of the anonymous function when it's run. That makes the anonymous function work like a simple closure which you, the programmer, can effectively ignore.
Also, you can use two different syntaxes for IIFEs:
(function() {}());
(function() {})();
It's unlikely you'll have problems using either one, but there are some differences that crop up when you've got some syntax problems in your code. IMO you're better off sticking with the first, which is also more clear to read.
--
As to your second question: are the following two equivalent?
(function(){})();
and
function initSomething() {}
initSomething();
Errm, wellll, sort of. You could probably get away with treating them the same, because for most purposes they work the same. That is, in your program you will get the same results with either one (in both cases you're defining a function, then calling it).
But it's important to note the difference between an anonymous function and a function declaration. You can think of anonymous functions as executables, or blocks of code that you can pass around to work as glue when you don't want to define a real, named function. Because they're anonymous, they don't exist in the scope chain, and you can't, for instance, add properties to an anonymous function object and use them later—unless you assign it to a variable first, in which case it's no longer anonymous!
Declaring a function is totally different. It creates a constructor that you can use again and again to create new objects (using new
) that can inherit the original function's properties. This is useful for many things, particularly when using frameworks like AngularJS.
function Friend(likes_you) {
//private property, only accessible to instances of this object
this.likes_you = likes_you;
}
//add a function as a property of Friend's prototype -
//instances of the Friend constructor can call this function
Friend.prototype.greet = function(greeting) {
if (this.likes_you) {
alert(greeting);
} else {
alert("I don't like you");
}
};
var you = new Friend(true);
you.greet('hello!'); //alerts 'hello!'
var guy = new Friend(false); //can make as any Friend objects as we want
guy.greet('hello!'); //alerts "I don't like you"
Of course, you don't need to do anything like this, but it's good to know what JavaScript is really doing. And that's just the start of the JS rabbit hole ...