可以在JavaScript中的语句内部显示函数声明吗?

Šim*_*das 17 javascript

请将官方ECMAScript规范视为您的答案来源,而不是特定浏览器供应商发布的文档.(我知道Mozilla使用"函数语句"扩展其JavaScript实现.)

那么,根据ECMAScript规范,ergo,其中定义的句法产品,这是有效的吗?

if (foo) {
    function x() { return; }
}
Run Code Online (Sandbox Code Playgroud)

更新:我的问题也可以这样说: Statement生产是否包含 FunctionDeclaration生产?

结论:答案是否定的.

Dan*_*llo 20

我不同意其他有效的答案.

根据ECMA-262第5版规范,Blocks只能包含Statements(第12.1节):

Block :
   { StatementList opt }

StatementList :
   Statement
   StatementList  Statement
Run Code Online (Sandbox Code Playgroud)

但是规范没有定义函数语句,只有a FunctionDeclaration和a FunctionExpression.规范在第12节中进一步说明了这一点:

已知几种广泛使用的ECMAScript实现支持使用FunctionDeclarationas Statement.然而,在应用于这种语义的语义中的实现之间存在显着且不可调和的变化FunctionDeclarations.由于这些不可调和的差异,使用FunctionDeclarationa Statement导致代码在实现中不可靠地移植.建议ECMAScript实现在FunctionDeclaration遇到此类用法时不允许使用此类用法或发出警告.ECMAScript的未来版本可以定义用于在Statement上下文中声明函数的替代可移植方法.

如需进一步阅读,您可能还有兴趣查看comp.lang.javascript常见问题解答第4.2节:

4.2什么是函数语句?

函数语句一词被广泛而错误地用于描述a FunctionDeclaration.这是误导性的,因为在ECMAScript中,a FunctionDeclaration不是a Statement; 程序中有一些地方Statement允许a但是a FunctionDeclaration不允许.为了增加这种混淆,一些实现,特别是Mozillas',提供了一种称为函数语句的语法扩展.ECMA-262,第3版和第5版第16节允许这样做.

非标准函数语句示例:

// 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) }
Run Code Online (Sandbox Code Playgroud)

使用函数语句的代码有三种已知的解释.一些实现Fze按顺序处理为Statement.其他人,包括JScript,Fze在进入它出现的执行上下文时进行评估.还有一些,特别是DMDScript和BESEN的默认配置,抛出一个SyntaxError.

对于跨实现的一致行为,不要使用函数语句; 使用FunctionExpressionFunctionDeclaration代替.

FunctionExpression示例(有效):

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

FunctionDeclaration示例(有效):

// Program code
function aa(b,a){return b.unselectable=a}
Run Code Online (Sandbox Code Playgroud)