0

I've always thought of parenthesis as mainly being a way to organize code and make sure order of operations went in the right order. However, I've recently encountered some code that makes me wonder if they're doing something else behind the scenes.

I had assumed that the parenthesis wrapping the function definition in this code block were there for readability:

(function foo(){alert('hello world!')})();

However, if I remove them, I get an error.

function foo(){alert('hello world!')}(); //SyntaxError: Unexpected token )

This sort of makes sense because I can imagine that the } at the end of the function ends the statement and the () is called independent of the function (which throws the same error), while wrapping the function in parenthesis returns the function, which can then be called.

However, the following code works:

(function foo(){alert('hello world!')}())

This is the same as the second code chunk, except the entire thing is wrapped in parenthesis. I have no idea why this doesn't throw the same error as function foo(){alert('hello world!')}(), and was hoping someone could cast some light on the issue.

ckersch
  • 7,507
  • 2
  • 37
  • 44
  • 3
    http://benalman.com/news/2010/11/immediately-invoked-function-expression/ – adeneo Aug 28 '14 at 19:39
  • 1
    It is a function statement (the form that errors) vs a function expression. – user2864740 Aug 28 '14 at 19:39
  • Reopening - not that I disagree that this should be closed as a duplicate, but that there are [several] better duplicates. For example, see http://stackoverflow.com/questions/9053842/advanced-javascript-why-is-this-function-wrapped-in-parentheses?lq=1 – user2864740 Aug 28 '14 at 19:41
  • You can also use `+function foo(){alert('hello world!')}();`, `-function foo(){alert('hello world!')}();`, `!function foo(){alert('hello world!')}();`, ... – Oriol Aug 28 '14 at 19:42
  • `(function foo(){alert('hello world!')})();` and `(function foo(){alert('hello world!')}())` are equivalent. In general, `A` is equivalent to `(A)`, so `(A())` and `(A)()` are the same. In both cases a **function expression** is evaluated (which results in a function) and the `()` are interpreted as a function **call**. In case of however `function foo(){alert('hello world!')}();` the line is interpreted as function **declaration** (functions are special) and the **grouping operator**. The grouping operator requires to contain an expression, so this throws a syntax error. – Felix Kling Aug 28 '14 at 19:44
  • I guess I'd seen IIFEs before, but always thought that the extra parens were a formality. @adeneo 's link explains this well: the parens can't contain statements, so the function definition is coerced into an expression. – ckersch Aug 28 '14 at 19:44
  • The same behavior also causes (if(1){}) to throw an error. – ckersch Aug 28 '14 at 19:45
  • @ckersch: Again `(...)` is interpreted as the grouping operator. It can only contain **expressions**, not **statements**. The `if` statement is a .... statement. `()` is invalid because it *must* contain an expression. `(if(...){})` is invalid because `if...` is not an expression. But `(function() {...})` is valid because the function definition is interpreted as function *expression*. – Felix Kling Aug 28 '14 at 19:47

0 Answers0