として解析されているため機能しません。またFunctionDeclaration
、関数宣言の名前識別子は必須です。
括弧で囲むと、として評価され、FunctionExpression
関数式に名前を付けるかどうかを指定できます。
aの文法はFunctionDeclaration
次のようになります。
function Identifier ( FormalParameterListopt ) { FunctionBody }
そしてFunctionExpression
s:
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
あなたが見ることができるようにIdentifier
(識別子OPTを)トークンでは、FunctionExpression
したがって、我々は定義された名前のない関数式を持つことができ、オプションであります:
(function () {
alert(2 + 2);
}());
または名前付き関数式:
(function foo() {
alert(2 + 2);
}());
括弧(以前はグループ化演算子と呼ばれていました)は式のみを囲むことができ、関数式が評価されます。
2つの文法プロダクションはあいまいになる可能性があり、たとえば次のようにまったく同じに見える場合があります。
function foo () {} // FunctionDeclaration
0,function foo () {} // FunctionExpression
パーサーFunctionDeclaration
はFunctionExpression
、それが現れるコンテキストに応じて、それがaかかを知っています。
上記の例では、カンマ演算子は式のみを処理することもできるため、2番目の式は式です。
一方、FunctionDeclaration
sは実際には、「Program
」コードと呼ばれるものだけに現れる可能性があります。これは、グローバルスコープの外側のコードと、FunctionBody
他の関数の内側のコードを意味します。
ブロック内の関数は、予期しない動作を引き起こす可能性があるため、避ける必要があります。例:
if (true) {
function foo() {
alert('true');
}
} else {
function foo() {
alert('false!');
}
}
foo(); // true? false? why?
上記のコードは実際にはを生成するはずですSyntaxError
。なぜなら、a Block
はステートメントのみを含むことができる(そしてECMAScript仕様は関数ステートメントを定義しない)ためですが、ほとんどの実装は許容され、2番目の関数(アラートを出す関数)を取るだけ'false!'
です。
Mozillaの実装-Rhino、SpiderMonkey-は異なる動作をします。それらの文法には非標準の関数ステートメントが含まれています。つまり、関数はs で発生するように、解析時ではなく実行時に評価されますFunctionDeclaration
。これらの実装では、最初の関数を定義します。
関数はさまざまな方法で宣言できます。以下を比較してください。
1- 変数multiplyに割り当てられたFunctionコンストラクターで定義された関数:
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-名前付き関数式func_nameは、変数multiplyに割り当てられています。
var multiply = function func_name(x, y) {
return x * y;
};