10

私は即時呼び出し関数式(IIFE)の動作を研究していますが、その間に次のような状況に遭遇しました。

(function () {
    document.write("bar");
})

(function () {
    document.write("foo");
}());

1つ目は、関数式を呼び出さずに内部に持つ単なるグループ化演算子だと思いました。2つ目は、関数式を使用したグループ化演算子ですが、現在はその関数を呼び出しています。

私が奇妙だと思うのは、両方が呼び出されるということです、それはなぜですか?

(function () {
    document.write("bar");
})

var x = 1;

(function () {
    document.write("foo");
}());

間に変数宣言を挿入して2つを壊すと、fooと書くだけです。これは私が期待したことです。

4

3 に答える 3

16

最初の関数式の後にセミコロンを忘れたため:

(function () {
    document.write("bar");
});

それ以外の場合、2番目の「グループ化演算子」は関数呼び出しとして解釈されます。したがって、この:

(function a() {
    ...
})

(function b() {
    ...
}());

基本的には次のものと同じです。

function b() {
    ...
}

(function a() {
    ...
})(b());

並べ替えると、少し見やすくなります。空白文字はJavaScriptでは意味がなく、無視されることに注意してください。

于 2013-02-11T11:06:50.787 に答える
4

Felix Klingが正しく指摘したように、セミコロンがないため、2番目のIIFEの周りの括弧は、関数式をグループ化するだけでなく、関数呼び出しとして解釈されます。改行がないと、はるかに明確になります。

(function () {
    document.write("bar");
})(function () {
    document.write("foo");
}());

またはいくつかの再調整を伴う:

(function () {
    document.write("bar");
})(
    function () {
        document.write("foo");
    }()
);

最初の関数式が呼び出され、2番目の関数式の結果が最初で唯一の引数になります。また、2番目の関数が最初に呼び出され、その結果が引数として最初の関数に渡されるため、はでfoobarはなく書き込まれることに注意してください。barfoo

于 2013-02-11T11:10:40.097 に答える
3

次のようなIIFEを作成することもできます。(function () {})()

セミコロンを省略することにより、最初のコードスニペットは実際に最初の関数を呼び出し、2番目のIIFEが最初のパラメーターとして渡されます。

                    executing as parameter for the first IIFE
                                               \/ 
(function () {document.write("bar");})( (function () {document.write("foo");}());)

これは最初に印刷fooされ、次にbar異なります:

(function () {
    document.write("bar");
})();

(function () {
    document.write("foo");
}());

印刷barfooするか

(function () {
    document.write("bar");
});

(function () {
    document.write("foo");
}());

ここで、最初のものは単にグループ化演算子と見なされます。

于 2013-02-11T11:10:54.467 に答える