web-dev-qa-db-ja.com

JavaScript匿名関数の即時呼び出し/実行(式と宣言)

可能性のある重複:
JavaScriptの関数式と宣言の違いは何ですか?
JavaScriptのカプセル化された匿名関数の構文の説明

なぜこれ:

(function () {
    //code
}());

この:

var f = function () {
    //code
}();

動作しますが、これ:

function () {
    //code
}();

ではない?まったく同じように見えます-匿名関数が定義され、すぐに呼び出されます。誰かがそれを説明するJavaScript/ECMAScript標準から引用できますか?

[〜#〜] update [〜#〜]:みんなに答えてくれてありがとう!つまり、関数式と関数宣言の関係です。 このStack Overflowの回答ECMAScript標準 セクション13、およびこのすばらしい記事を参照してください:名前付き関数式demystified

回答を要約するには:

  1. グループ化演算子()が適用されるため、最初のスニペットは式として解釈されます- ECMAScript標準 セクション11.1.6を参照してください。

  2. 2番目のスニペットでは、関数は代入演算子=の右側にあるため、式として解釈されます。

  3. 3番目のスニペットには、インタープリターが式として関数を読み取ることを許可するものがないため、宣言がないと見なされます。これは、識別子なしでは無効です(ただし、Geckoはパスしますが、() (考えられるように)演算子は何にも適用されません)。

58
lxa

最初の2つのケースは関数式を示しており、(_1+1_またはx*f(4))のような式が表示される場所であればどこにでも表示できます。 _1+1_が_2_に評価される方法と同様に、これらの式は対応する関数に評価されます。


3番目のケースは、関数のデクリレーションstatementであり、他のステートメント(ifまたはwhileステートメント)。

Funcion宣言ステートメントを介して匿名関数を宣言しようとする意味はあまりありません。そうしないと、後で関数への参照を取得できなくなるからです。


最初の2つのケースのように_(_または_var x =_を開く必要があるのは、式コンテキストで次のビットを強制的に解析するためです。 (たとえば、_var x = if ..._を実行できない方法を考えてください)。 functionを最初に置くだけの場合、宣言ステートメントとして解析されます。

21
hugomg

最初の2つは関数式と呼ばれるものです。つまり、インラインであり、JSコードの実行時に解釈されます。

3番目は関数宣言であり、コードのコンパイル時に解釈されます。コンパイル時に解釈されるため、他のコードはまだ実行されていないため、すぐに実行することはできません。

例を示すには:

// foo == undefined
// bar == function

function bar(){ .. }
var foo = function(){ ... }

// foo == function
// bar == function

簡単に言うと、Word functionの前に何もない場合は、宣言です。何かがそれに先行するときはいつでも、それは表現です。

4
Mark Kahn

匿名関数については、スタックオーバーフローの質問なぜ同じ行で匿名関数を呼び出す必要があるのですか?で説明されています。

0
Jason Gennaro

簡単な考え方を次に示します。functionが行の最初のキーワードである場合、パーサーは行の残りを関数宣言として解釈します。つまり、関数に名前を付けるのを忘れたかのように、次のような記述を試みていると考えられます。

function foo(){ 
    // code
}

これを回避する方法は、いくつかの括弧で関数全体をラップするか、変数割り当ての一部にすることです。どちらの場合でも、functionを行に戻し、パーサーが関数宣言を書いていないことを認識できるようにします。

functionを行の先頭に表示し、それでも関数式と関数宣言を区別できるようにするのは簡単なことのように思えますが、JavaScriptが最初に設計されたときはさほど簡単ではなかったと思います。

0
Andrew