Dmitry said:
Technically, there are no function statements in ES5. Function
declarations are still /SourceElement/'s and so are only allowed in
/Program/ and /FunctionBody/.
What happens to "Function Statements" is still *not formally specified*.
As a matter of fact, if you look at Chapter 12, you can see this note:
"NOTE Â Â Â Several widely used implementations of ECMAScript are known to
support the use of FunctionDeclaration as a Statement. However there are
significant and irreconcilable variations among the implementations in
the semantics applied to such FunctionDeclarations. Because of these
irreconcilable difference, the use of a FunctionDeclaration as a
Statement results in code that is not reliably portable among
implementations. It is recommended that ECMAScript implementations
either disallow this usage of FunctionDeclaration or issue a warning
when such a usage is encountered. Future editions of ECMAScript may
define alternative portable means for declaring functions in a Statement
context."
Yeah, already discussed regarding ECMA-262-3. And nevertheless,
implementation of Spidermonkey (and other newer *monkeys) still seems
to me more logical (e.g. for if-else statements) regardless
specification. I don't see the big sense in words they say "an
ExpressionStatement cannot start with the `function` keyword because
that might make it ambiguous with a FunctionDeclaration"? If it's in
That's because it would be useless (as it is specified now).Let's
assume Function Expression is allowed in statement:
 if (true) {
  function(){}
 }
or:
 if (true) {
  function f(){}
 }
You see what happens?
We end up with essentially "dead" code: Identifier (if present) is never
made available to the outer scope (as per function expression rules);
function is instantiated and can immediately be garbage collected.
What's the point? Surely, it's better to disallow this kind of scenario
earlier — on a syntactic level.
But it should be treated as `FE` for not to be useless. It should be
treated as a special form, sort of combination of `FD + FE`, which
means: affecting on the scope by the *same* rules as `var` and `FD`,
but creating in runtime just like `FE`. Maybe it won't be so useful
(or even useless) in some statements blocks, but e.g. in `if-else`
blocks it's very useful. And in discussion of the link you gave
bellow, I agree wit Igor Bukanov and Brendan Eich.
So, the main reason is not "it's useless", but "because that might
make it ambiguous with a FunctionDeclaration", which means scanner/
parser can't resolve with what kind of object it deals: with FD which
should be created on entering the context (what most implementations
do) or FE which should be created in runtime.
It's absolutely should be same as for:
function test() {}();
Here scanner/parser can't determinate what's this: FD or FE, so it
truly throws an exception. Just then, when we surround this case with
grouping operator (as one of the ways to transform it to `FE`),
scanner knows that it's `FE`:
(function test() {})();
Meanwhile, in this case, it knows it without our manually instruction
(with grouping operator):
var o = {
bar: function () {
return 'test';
}();
};
alert(o.bar); // "test"
To make it easier, they wrote: `[lookahead ∉ {{, function}]
Expression ;` - and that's the reason, but not "that's useless". And
Spidermonkey still got its right (by section 16) and make extension -
`FS` (but you sure know it all yourself).
/ds