The code is using a FunctionDeclaration
outside of a top-level statement (see SourceElement
) and are thus invoking Browser-Defined Behavior.
Per the ECMAScript Grammar the 'correct' solution would be to throw a SyntaxError, but due to implementations accepting the construct this is relaxed to merely a note in the specification.
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.
In summary:
function f () {
function g() {} /* FunctionDeclaration as SourceElement - OK! */
}
function f () {
if (x) {
function g() {} /* FunctionDeclaration as Statement;
Browser-defined behavior */
}
}
function f () {
var g;
if (x) {
g = function () {} /* FunctionExpression - OK! */
}
}
In Strict Mode, Firefox throws a SyntaxError:
[In Firefox] SyntaxError: in strict mode code, functions may be declared only at top level or immediately within another function
Neither Chrome (45) nor IE (11) follow this optional behavior.
This prohibition isn't strict mode proper, because such function statements are an extension of basic ES5. But it is the - "Don't Pollute Strict Mode with Non-standard Declaration Forms" - recommendation of the ECMAScript committee, and [Firefox wil] implement it.