6

bit of a silly question perhaps.

But I want to understand why the syntax on the self-executing function and the callback it has is so different to all the other JS syntax..

(function () {
})()

I just need to understand why its valid to encapsulate it with () I wouldn't have guessed that to be valid, and then the extra () afterwards for the callback, (which just sits directly after it, I also wouldn't have expected that to be valid.

Is anyone able to explain this to me?

MrTux
  • 32,350
  • 30
  • 109
  • 146
williamsandonz
  • 15,864
  • 23
  • 100
  • 186
  • possible duplicate of [How does an anonymous function in JavaScript work?](http://stackoverflow.com/questions/1140089/how-does-an-anonymous-function-in-javascript-work) – ziesemer Feb 29 '12 at 01:55
  • An alternate way of doing the same thing, which avoids all the parenthesis, is `new function() {...};`. New invokes the function for you. – jpsimons Feb 29 '12 at 02:03
  • @darkporter: One major difference is that `new function() {...}` invokes the function *as a constructor*. So `this` will be different inside, and the expression will evaluate to the newly-created object instead of to whatever `function() {...}` returns. (I'm guessing you already know this, but I think it's worth making it explicit for the benefit of those who don't!) – ruakh Feb 29 '12 at 02:07
  • @ruakh: Can you explain that a little more? – qwertymk Feb 29 '12 at 03:17
  • @qwertymk: If `f` is a function, then `new f` creates a new object, invokes `f` with `this` being that new object, and returns the object. For example, `new String` creates and returns a new string, and `new function () { this.foo = 'bar'; }` creates and returns a new object with its `foo` property set to `'bar'`. – ruakh Feb 29 '12 at 03:31
  • _"and then the extra `()` afterwards for the callback"_ - that's not a "callback". The term "callback" (usually) refers to when you pass a function reference to another function so that that other function can call it. It's a call _back_ because it is often used as a way for a library to pass information back to your code. – nnnnnn Feb 29 '12 at 03:35

4 Answers4

14

The function (...) {...} part is a function expression, that is, an expression that represents a function. The only reason it has to be wrapped in parentheses in this case is that if the keyword function is the very first thing in a statement, then the statement is assumed to be a function statement, that is, a function declaration. (Actually, it doesn't necessarily have to be wrapped in parentheses; it also works to prefix it with a +, or in general to put any sort of token before function that prevents the function-statement interpretation.)

The () part after the function expression is the same as the normal () for calling a function. This:

(function (...) {...})(...);

is (aside from the temporary variable) the same as this:

var f = function (...) {...};
f();

which is equivalent to this:

function f(...) {...};
f();
ruakh
  • 175,680
  • 26
  • 273
  • 307
  • Thanks everyone, thanks ruakh. I've got what your saying. I guess the hump is understand the 3 ways that a function can actually be declared. – williamsandonz Feb 29 '12 at 02:31
2

Essentially the outer parentheses allow the function object to be fully interpreted and instantiated, so that once you exit the scope of those parentheses the function object is ready to be called.

David Mason
  • 2,917
  • 4
  • 30
  • 45
2

See here:

When declaring as you did, you are using it as a function expression (3rd way of defining the function from the above link). As with any expression, this (expression) evaluates to expression - parentheses are used here is establish precedence where necessary. So you can write this for example:

var f = function(a) {
    var s = (((( 1 )))) + (((( a ))));
    console.log(s);
};

((((( f ))))) (2);

(live example) and then remove all the unnecessary parentheses with the same result (which is printing of 1 + 2 = 3, essentially). The result of:

(function(...) { ... }) 

is a function that accepts some arguments and has a body to be executed. This:

(function(...) { ... })()

is pretty much equivalent to:

var f = (function(...) { ... });
// Now f is a function that can be called
f();

Anonymous functions are useful, among other things, for two reasons - they are anonymous (i.e. they don't create additional names - see again the above SOq link) and they are "containers" for other stuff that doesn't need to be global.

Community
  • 1
  • 1
icyrock.com
  • 27,952
  • 4
  • 66
  • 85
0

What you have here is an Immediately-invoked function expression also known as IFFE (read iffy) and is a design pattern which produces lexical scope using JS function scoping. These are used to avoid variable hoisting, polluting the global environment and simultaneously allowing public acces to methods while retaining the local privacy of variables declared whithin the function. The key to understanding this is that JS has function scope and not block scope and passes values by reference inside a closure. You can read further into this at Immediately-invoked function expression.

hyprstack
  • 4,043
  • 6
  • 46
  • 89