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?
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?
Share Improve this question edited May 2, 2015 at 10:37 MrTux 34k30 gold badges117 silver badges156 bronze badges asked Feb 29, 2012 at 1:49 williamsandonzwilliamsandonz 16.4k23 gold badges106 silver badges189 bronze badges 6- possible duplicate of How does an anonymous function in JavaScript work? – ziesemer Commented Feb 29, 2012 at 1:55
-
An alternate way of doing the same thing, which avoids all the parenthesis, is
new function() {...};
. New invokes the function for you. – jpsimons Commented Feb 29, 2012 at 2:03 -
@darkporter: One major difference is that
new function() {...}
invokes the function as a constructor. Sothis
will be different inside, and the expression will evaluate to the newly-created object instead of to whateverfunction() {...}
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 Commented Feb 29, 2012 at 2:07 - @ruakh: Can you explain that a little more? – qwertymk Commented Feb 29, 2012 at 3:17
-
@qwertymk: If
f
is a function, thennew f
creates a new object, invokesf
withthis
being that new object, and returns the object. For example,new String
creates and returns a new string, andnew function () { this.foo = 'bar'; }
creates and returns a new object with itsfoo
property set to'bar'
. – ruakh Commented Feb 29, 2012 at 3:31
4 Answers
Reset to default 14The 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();
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.
See here:
- Why do you need to invoke an anonymous function on the same line?
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.
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.