3

What exactly is this syntax in Javascript? I see it used (or abused?) often:

(function(){})();

I get that it creates an anonymous function and then executes it. But, can't figure out why it has to be that way. Isn't that equivalent to a more readable form:

 function initSomething() {}
 initSomething();

EDIT: Thanks all for the great responses that helped me understand an idiom in Javascript.

Luis Artola
  • 771
  • 6
  • 20
  • 1
    It's an immediately/self-invoked function expression. – David Thomas Jul 16 '13 at 17:08
  • `(function(){alert("anonymous function!!!")})()` – AllTooSir Jul 16 '13 at 17:09
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope – Andbdrew Jul 16 '13 at 17:09
  • 1
    @TheNewIdiot, This has nothing to do with obfuscation. – Brad Jul 16 '13 at 17:09
  • 2
    You're asking what it is, then you say that you already know. What exactly is your question? Are you asking why people use it instead of a named function? You seem to have shifted gears in the middle of your post. Who said "it has to be that way"? It doesn't. If you want to name a function that you'll never use again, then do it. –  Jul 16 '13 at 17:13
  • Great post by Ben Alman, creator of Grunt: http://benalman.com/news/2010/11/immediately-invoked-function-expression/ – gustavohenke Jul 16 '13 at 17:13
  • @CrazyTrain one can write solid efficient code in many languages, but excellence comes from absorbing best practices and idioms specific to each language. This question was about understanding what the peculiarities of Javascript programming are. I much rather write code that reads like it was meant for Javascript than just code that works but reads like C or Python or something else. – Luis Artola Jul 16 '13 at 17:36
  • Sure, but then you may want to edit your question to reflect what you're actually asking. –  Jul 16 '13 at 17:43

6 Answers6

4

The function in your second example is no longer anonymous... it has a name, initSomething.

The first syntax is commonly used to set up a closure... trapping var x, y, z and what not within it so that they don't conflict with any other variables with the same name outside of the closure.

Sparko
  • 735
  • 6
  • 15
Brad
  • 159,648
  • 54
  • 349
  • 530
3

It's a self-invoked anonymous function.

function(){} is an anonymous function-literal.

(function(){})() invokes that literal.

Since this is an anonymous function that invokes itself, it is a self-invoked anonymous function.

The advantage of the first form over the second is that it gives you an easy way to encapsulate code that you don't want polluting the global namespace.

You're also not needlessly creating a function initSomething that is part of the global namespace now, and that could potentially clobber something else.

If you're interested in more information, you can look here as well.

Community
  • 1
  • 1
Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
3

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 ...

user428517
  • 4,132
  • 1
  • 22
  • 39
  • Ah, the equivalent of monkey-patching in Python. Nice! Thanks for the explanation. All other answers were good too. But I particularly liked the contrast of constructs in this one. The one thing that I find ironic is that most code I see using this autoexecutable anonymous functions is that they normally have a comment line describing what it is - which is in essence a function name. So, if () creates a scope in Javascript, would this be more readable while still not polluting the global scope? (function initSomething(){})(); – Luis Artola Jul 16 '13 at 17:54
  • `()` does NOT create scope in javascript. parens are used for grouping code or invoking functions (both of which are being done here). functions create scope. the `()` at the end of the anonymous function *invokes* the function; it does not create scope. It's common to see this sort of wrapper written like `(function() {}());`. This makes it clear that the `()` invokes the function, while the parens around the entire function tell the interpreter that you want to produce a value (i.e. the result of the function after it runs), not declare a function. – user428517 Jul 16 '13 at 18:02
  • your last question doesn't make sense to me - there's no need to name a function if you only want to use it as a scope wrapper. `(function() {}());` is THE best way to declare an IIFE. Giving the wrapper function a name will add the function as a property of the global `window` object (i.e. polluting the global scope), which is what you're trying to avoid in the first place. So just use the wrapper above and put ALL your code inside the `{}` (or, if you have multiple files, put all the code inside each into a wrapper). – user428517 Jul 16 '13 at 18:08
  • and yes, javascript's prototypal inheritence is very similar to monkey-patching in python or any general concept of "mixins" you might find in languages. js's objects are very similar to ruby's too, although it's important to remember javascript has NO classes - prototypal inheritence works differently but can be used to accomplish many of the same things as classes in other languages – user428517 Jul 16 '13 at 18:12
2

This is a immediately-invoked function expression

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

Taken from wikipedia, since it's well explained.

An immediately-invoked function expression (or IIFE, pronounced "iffy") is a JavaScript design pattern which produces a lexical scope using JavaScript's function scoping. Immediately-invoked function expressions can be used to avoid variable hoisting from within blocks, protect against polluting the global environment and simultaneously allow public access to methods while retaining privacy for variables defined within the function.

See here for a more detailed explanation.

I get that it creates an anonymous function and then executes it. But, can't figure out why it has to be that way. Isn't that equivalent to a more readable form:

function initSomething() {}
initSomething();

It's not the same since initSomething can be still referenced and thus is not anonymous.

intuitivepixel
  • 23,302
  • 3
  • 57
  • 51
1

You can do it both ways, but the first case is an anonymous function (it doesnt have a name, so you avoid conflicts and so on).

Fernando
  • 7,785
  • 6
  • 49
  • 81
1

basically it's an un-named (anonymous) function that is executed immediately as soon as the function is loaded.

The reason for this method is to keep as much off of the global scope as possible and to isolate your variables from any others that may be defined elsewhere, you can define variables and other functions inside the function and it won't spam all of those within your global scope.

Lochemage
  • 3,974
  • 11
  • 11