Can function declarations be displayed inside statements in JavaScript?

Please consider the official ECMAScript specification as the source of your response, and not a document published by a specific browser provider. (I know that Mozilla extends its JavaScript implementation with "function statements".)

So, according to the ECMAScript specification, ergo, syntax production defined in it, is it really?

if (foo) { function x() { return; } } 

Update: My question can also be formulated as follows: Can a Statement production contain a FunctionDeclaration function?

Conclusion: The answer is NO.

+17
javascript
Nov 01 '10 at 17:16
source share
7 answers

I disagree with the other answers that say this is valid.

According to the ECMA-262 specification, the 5th Edition Blocks can only contain Statements ( Section 12.1 ):

 Block : { StatementList opt } StatementList : Statement StatementList Statement 

However, the specification does not define a function operator, but only FunctionDeclaration and a FunctionExpression . The spectrum goes further to mark this in Section 12 :

It is known that several commonly used ECMAScript implementations support the use of FunctionDeclaration as Statement . However, there are significant and irreconcilable variations among implementations in semantics applied to such FunctionDeclarations . Due to this irreconcilable difference, using FunctionDeclaration as a Statement causes the code to not be reliably ported among implementations. It is recommended that ECMAScript implementations either prohibit this use of FunctionDeclaration or issue a warning when such use is encountered. Future releases of ECMAScript may define alternative portable means for declaring functions in the context of Statement .

For further reading, you may also be interested in learning the comp.lang.javascript FAQ Section 4.2 :

4.2 What is a function instruction?

The term function operator is widely and mistakenly used to describe FunctionDeclaration . This is misleading because in ECMAScript a FunctionDeclaration not a Statement ; There are places in the program where Statement allowed, but FunctionDeclaration not. To add to this confusion, some implementations, notably Mozillas', provide a syntax extension called a function statement. This is permitted by section 16 of ECMA-262, editions 3 and 5.

An example of a non-standard function:

 // Nonstandard syntax, found in GMail source code. DO NOT USE. try { // FunctionDeclaration not allowed in Block. function Fze(b,a){return b.unselectable=a} /*...*/ } catch(e) { _DumpException(e) } 

Code that uses a function operator has three well-known interpretations. Some implementations execute Fze as an expression, in order. Others, including JScript, evaluate Fze when entering the execution context in which it appears. Others, in particular DMDScript and the standard BESEN configuration, throw a SyntaxError .

For consistent behavior in all implementations, do not use a function statement; use FunctionExpression or FunctionDeclaration instead.

FunctionExpression example (valid):

 var Fze; try { Fze = function(b,a){return b.unselectable=a}; /*...*/ } catch(e) { _DumpException(e) } 

FunctionDeclaration example (valid):

 // Program code function aa(b,a){return b.unselectable=a} 
+19
Nov 01 '10 at 17:34
source share

I'm not sure how to read this, but the ECMA-262 V5 says the following:

NOTE. It is known that several commonly used ECMAScript implementations support the use of FunctionDeclaration as a Statement. However, there are significant and irreconcilable variations among implementations in semantics applied to such functions. Because of these irreconcilable differences, using FunctionDeclaration as a statement causes the code to not be reliably ported among implementations. It is recommended that ECMAScript implementations either prohibit this use of FunctionDeclaration or issue a warning when such use is encountered. Future releases of ECMAScript may define alternative portable means for declaring functions in the context of Statement.

If I understand this correctly, strictly speaking, this means that function declarations cannot be inside blocks at all, because blocks can only contain expressions.

I may be completely wrong in my interpretation, although - I am not familiar with the internal development of ECMAScript.

+3
Nov 01 '10 at 17:32
source share

No, this is not valid. Function declarations can only be displayed as "source elements" that are either in the global scope, or immediately within another function definition, outside of all other operators. From the ECMA-262 specification:

FunctionBody: SourceElements

Program: SourceElements

SourceElement: Statement | FunctionDeclaration

There is no other work in grammar that FunctionDeclaration allows.

Only function expressions are allowed in an expression:

MemberExpression: FunctionExpression

...

Statement: ExpressionStatement

Edit: Recently, another issue has been discussed. See Comments on this answer - I also thought before that this might be acceptable, but the grammar clearly states that this is not true.

+3
Nov 01 '10 at 17:35
source share

From ECMA 262, chapter 14

  • Program syntax

Program: SourceElements SourceElements: SourceElement SourceElements Element SourceElement SourceElement: Statement Element Semantics FunctionDeclaration

Production Program: SourceElements is rated as follows:

  • Process SourceElements for function declarations.

  • Evaluate the source elements.

  • Return result (2).

SourceElements production: The SourceElement element is processed to declare functions as follows:

  • Process SourceElement for function declarations.

SourceElements production: The SourceElement element is evaluated as follows:

  • Rate the original item.

  • Return result (1).

SourceElements production: The SourceElements element of the SourceElement is processed for function declarations as follows:

  • Process SourceElements for function declarations.

  • Process SourceElement for function declarations.

SourceElements production: SourceElements SourceElement is evaluated as follows:

  • Evaluate the source elements.

  • If Result (1) is abrupt termination, return Result (1)

  • Rate the original item.

  • Return Result (3).

Source SourceElement: * The operation is processed for the function * without taking any action.

Source SourceElement: * A statement is evaluated as follows: *

1. Calculate the expression.

2. Return result (1).

Source SourceElement: A Declration function is processed to declare functions as follows:

  • FunctionDeclaration function for function declarations (see section 13).

Source SourceElement: FunctionDeclaration is evaluated as follows:

  • Return (regular, empty, empty).

Azner is officially NOT. (Shim Vidas convinced me of another question)

But the exception is not indicated either because it fails or works silently, depending on the implementation of the browser.

+2
Nov 01 '10 at 17:38
source share

ECMA-262 version 5 says that it should not be valid:

Function Decoding is allowed only for display in the program or FunctionBody. Syntactically, they cannot appear in Block ({...}) - for example, if if, while for statements. This is because Blocks can only contain Statements, not SourceElements, which are FunctionDeclaration. If we look at the production rules, we can see that the only way of expression is allowed inside the block when it is part of an ExpressionStatement. However, ExpressionStatement is explicit not to start with a โ€œfunctionโ€ keyword, and this is exactly what makes FunctionExpression invalid as part of a statement or block (note this Block is just a Reporting list).

However, it seems that not many interpreters obey this rule. Kangax says they should be treated as syntax errors on this page :

Due to these limitations, whenever a function appears in a block (for example, in the previous example), it should actually be considered as syntax error, not function declaration or expression. The problem is that almost none of the implementations that I saw analyzing these functions is strictly beyond the rules (exceptions are BESEN and DMDScript). They interpret them in, among other things.

+1
Nov 01 '10 at 17:35
source share

In the ECMAScript standard, FunctionDeclaration is not defined as Statement, and Statement is not defined as capable of containing FunctionDeclaration, therefore they are incompatible in accordance with the standard (although in practice, every JavaScript interpreter will try to do something reasonable, although not consistent between implementations).

0
Nov 01 '10 at 17:44
source share

Yes it really is.

All operator blocks (i.e., all inside curly brackets) can have additional instructions and declarations, including functions.

That way you can also define functions inside functions, etc.

Here is ECMA-262 v1 - http://www.mozilla.org/js/language/E262.pdf

-one
Nov 01 '10 at 17:26
source share



All Articles