0

I know about Self-Executing Anonymous. And usually we create them as

(function(){ return 1;})()

the reason - parser feature which didn't run if we use

function(){ return 1}()

But today I found that next code works too ( check brackets order )

(function(){ return 1;}())

function(){ return 1; }() still give me SyntaxError, as it should

Please explain why? Thx for reference to get more details

P.S. the question is about (function(){ return 1;}()) variant!

Vasiliy vvscode Vanchuk
  • 7,007
  • 2
  • 21
  • 44
  • you didn't close the paraenthesis in ( function(){ return 1; }() – Lunny May 16 '16 at 14:44
  • it's text which contains function -- there is all correct – Vasiliy vvscode Vanchuk May 16 '16 at 14:44
  • Because that is not correct syntax. This: `function(){ return 1; }()` simply is not defined as valid syntax as it is. – XCS May 16 '16 at 14:44
  • @LunZhang You mean in the last line? The first parenthesis isn’t part of the code. – Sebastian Simon May 16 '16 at 14:45
  • @Cristy The questions is why it WORKS, not 'why in NOT works' – Vasiliy vvscode Vanchuk May 16 '16 at 14:45
  • 1
    @VasiliyVanchuk Read this: https://en.wikipedia.org/wiki/Immediately-invoked_function_expression – XCS May 16 '16 at 14:46
  • @Cristy 'Douglas Crockford's style' didn't know. Thx – Vasiliy vvscode Vanchuk May 16 '16 at 14:47
  • 2
    It’s for the same reason `{a: 1, b: 2}[a]` doesn’t work. Here, `{`…`}` is a block, not an object. It’s because the `{` is interpreted as a statement, not an expression. `({a: 1, b: 2})[a]` or `({a: 1, b: 2}[a])` do work, because `(`…`)` forces the `{`…`}` to be interpreted as an expression (object). It’s exactly the same for functions, because there are function statements and function expressions. Why? Because that’s how JavaScript was designed. – Sebastian Simon May 16 '16 at 14:49
  • If you understand why the first one works, then you'll understand why the second works. The second should be no more mysterious than the first. –  May 16 '16 at 15:00
  • ...and [this answer](http://stackoverflow.com/a/1634321/1106925) to a different question gives a pretty detailed explanation of why either work and the last one doesn't. –  May 16 '16 at 15:04

2 Answers2

2
(function() {})()

and

(function() {}())

are equivalent.

To call second example you can include + operator before function

+function(){ return 1 }()

See Immediately-Invoked Function Expression (IIFE)

guest271314
  • 1
  • 15
  • 104
  • 177
  • There are better operators to use than `+`. The reason is that the `+` is overloaded as a binary operator, and so if you accidentally forget a semicolon after the previous expression, it will try to add that previous expression to the function. It's basically the same problem that people have with using `()`. If you're going to use an alternate operator to force an expression, use a unary operator, like `!` for example. –  May 16 '16 at 15:06
  • @squint _"There are better operators to use than `+`"_ , _"If you're going to use an alternate operator to force an expression, use a unary operator, like `!` for example."_ Yes, though not for this particular case; `!function(){ return 1 }()` returns `false` instead of `1` – guest271314 May 17 '16 at 00:33
  • @squint Alternatively, `;null, function(){ return 1 }();` – guest271314 May 17 '16 at 00:52
  • If the return value is being captured, there's no need for any operator to make the function a valid expression. But yeah, anything to avoid unexpected evaluation of the operator is better. I've used `void` at times in the past. –  May 17 '16 at 00:56
2

The phrase IIFE is a better term for these functions .. Immediately Invoked Function Expressions.

As for why they are the same: The outer parens () simply make an expression and the () together do the invocation.

(function(){ return 1;})()
is the same as:
(function(){ return 1;}())


(function(){ return 1;})()
becomes
(functionexpression)()
becomes
functionexpression()

and

(function(){ return 1;}())
becomes
(functionExpression())
becomes   
functionExpression()

for the same reason that

(3)+2 is the same as ((3)+2).

EDIT

function(){ return 1; }()

Does NOT work because a function statement is different from a function expression. Function statements cannot be immediately invoked.

Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74