它不起作用,因为它被解析为100,函数声明的名称标识符是mandatory.
当用括号括起来时,它的计算结果为100,函数表达式可以命名,也可以不命名.
FunctionDeclaration
的语法如下所示:
function Identifier ( FormalParameterListopt ) { FunctionBody }
和FunctionExpression
秒:
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
正如您所见,FunctionExpression
中的Identifier
(Identifieropt)标记是可选的,因此我们可以有一个不定义名称的函数表达式:
(function () {
alert(2 + 2);
}());
或named函数表达式:
(function foo() {
alert(2 + 2);
}());
括号(正式名称为the Grouping Operator)只能围绕表达式,函数表达式将被计算.
这两个语法产物可能是不明确的,它们看起来可能完全相同,例如:
function foo () {} // FunctionDeclaration
0,function foo () {} // FunctionExpression
解析器根据它出现的位置知道它是FunctionDeclaration
还是FunctionExpression
.
在上面的示例中,第二个是表达式,因为Comma operator也只能处理表达式.
另一方面,FunctionDeclaration
实际上只能出现在所谓的"Program
"代码中,这意味着在全局范围之外的代码,以及在其他FunctionBody
个函数中的代码.
应避免使用块内的函数,因为它们可能导致不可预测的行为,例如:
if (true) {
function foo() {
alert('true');
}
} else {
function foo() {
alert('false!');
}
}
foo(); // true? false? why?
上面的代码实际上应该生成SyntaxError
,因为Block
只能包含语句(ECMAScript规范没有定义任何Function语句),但是大多数实现都是可以容忍的,并且只会采用第二个函数,即警告'false!'
的函数.
Mozilla实现Rhino、SpiderMonkey有不同的行为.他们的语法包含non-standard Function语句,这意味着该函数将在run-time时求值,而不是在解析时求值,就像在FunctionDeclaration
时那样.在这些实现中,我们将定义第一个函数.
函数可以用不同的方式声明,compare the following:
1-用Function构造函数定义的函数分配给变量multiply:
var multiply = new Function("x", "y", "return x * y;");
2-名为multiply的函数的函数声明:
function multiply(x, y) {
return x * y;
}
3-分配给变量multiply的函数表达式:
var multiply = function (x, y) {
return x * y;
};
4-指定给变量multiply的命名函数表达式func_name:
var multiply = function func_name(x, y) {
return x * y;
};