It doesn't work because it is being parsed as a FunctionDeclaration
, and the name identifier of function declarations is mandatory .(它不起作用是因为它被解析为FunctionDeclaration
,并且函数声明的名称标识符是强制性的 。)
When you surround it with parentheses it is evaluated as a FunctionExpression
, and function expressions can be named or not.(当用括号将其括起来时,它将被视为FunctionExpression
,并且可以命名或不命名函数表达式。)
The grammar of a FunctionDeclaration
looks like this:(FunctionDeclaration
的语法如下所示:)
function Identifier ( FormalParameterListopt ) { FunctionBody }
And FunctionExpression
s:(和FunctionExpression
s:)
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
As you can see the Identifier
(Identifier opt ) token in FunctionExpression
is optional, therefore we can have a function expression without a name defined:(如您所见, FunctionExpression
的Identifier
(Identifier opt )标记是可选的,因此我们可以使用一个未定义名称的函数表达式:)
(function () {
alert(2 + 2);
}());
Or named function expression:(或命名函数表达式:)
(function foo() {
alert(2 + 2);
}());
The Parentheses (formally called the Grouping Operator ) can surround only expressions, and a function expression is evaluated.(括号(正式称为分组运算符 )只能包围表达式,并且会对函数表达式求值。)
The two grammar productions can be ambiguous, and they can look exactly the same, for example:(这两个语法产生可能会模棱两可,并且看起来可能完全相同,例如:)
function foo () {} // FunctionDeclaration
0,function foo () {} // FunctionExpression
The parser knows if it's a FunctionDeclaration
or a FunctionExpression
, depending on the context where it appears.(解析器知道它是FunctionDeclaration
还是FunctionExpression
,具体取决于它出现的上下文 。)
In the above example, the second one is an expression because the Comma operator can also handle only expressions.(在上面的示例中,第二个是表达式,因为逗号运算符也只能处理表达式。)
On the other hand, FunctionDeclaration
s could actually appear only in what's called " Program
" code, meaning code outside in the global scope, and inside the FunctionBody
of other functions.(另一方面, FunctionDeclaration
实际上只能出现在所谓的“ Program
”代码中,意味着在全局范围之外以及在其他函数的FunctionBody
内部。)
Functions inside blocks should be avoided, because they can lead an unpredictable behavior, eg:(应该避免在块内部使用函数,因为它们可能导致不可预测的行为,例如:)
if (true) { function foo() { alert('true'); } } else { function foo() { alert('false!'); } } foo(); // true? false? why?
The above code should actually produce a SyntaxError
, since a Block
can only contain statements (and the ECMAScript Specification doesn't define any function statement), but most implementations are tolerant, and will simply take the second function, the one which alerts 'false!'
(上面的代码实际上应该产生一个SyntaxError
,因为一个Block
只能包含语句(并且ECMAScript规范没有定义任何函数语句),但是大多数实现是可以容忍的,并且将仅采用第二个函数,该函数会警告'false!'
)
.(。)
The Mozilla implementations -Rhino, SpiderMonkey,- have a different behavior.(Mozilla实现-Rhino,SpiderMonkey-具有不同的行为。)
Their grammar contains a non-standard Function Statement, meaning that the function will be evaluated at run-time , not at parse time, as it happens with FunctionDeclaration
s.(它们的语法包含一个非标准的 Function语句,这意味着该函数将在运行时而不是在解析时进行评估,这与FunctionDeclaration
s一样。) In those implementations we will get the first function defined.(在这些实现中,我们将定义第一个函数。)
Functions can be declared in different ways, compare the following :(可以用不同的方式声明函数,请比较以下内容 :)
1- A function defined with the Function constructor assigned to the variable multiply :(1-一个函数,该函数使用分配给变量的Function构造函数 乘法 :)
var multiply = new Function("x", "y", "return x * y;");
2- A function declaration of a function named multiply :(2-名为乘法的函数的函数声明:)
function multiply(x, y) {
return x * y;
}
3- A function expression assigned to the variable multiply :(3-分配给变量multipli的函数表达式:)
var multiply = function (x, y) {
return x * y;
};
4- A named function expression func_name , assigned to the variable multiply :(4-命名函数表达式func_name ,分配给变量multipli :)
var multiply = function func_name(x, y) {
return x * y;
};