私は頭をクロージャーに巻き込もうとしています(どこかに冗談があります)、これに出くわしました:
(function () { /* do cool stuff */ })();
これはどのように作動しますか?関数を括弧に入れる目的は何ですか? 後で空の括弧が表示されるのはなぜですか?
私は頭をクロージャーに巻き込もうとしています(どこかに冗談があります)、これに出くわしました:
(function () { /* do cool stuff */ })();
これはどのように作動しますか?関数を括弧に入れる目的は何ですか? 後で空の括弧が表示されるのはなぜですか?
これのポイントは、クールなもので宣言された変数はグローバル名前空間では作成されないということです。JavaScript の関数は、そのようなスコープを作成します。実行したいJavaScriptがあるとします。これを行う場合:
var b = 1;
// stuff using b
また、他のコードで b を使用すると、残りの値が取得されます。(または、さらに悪いことに、コードの実行前に他のコードが b を設定し、後で古い値を取得しようとすると、その間に変更されていたでしょう。)
一方、次のコードがある場合、関数を宣言してから呼び出します。
function a() {
var b = 1;
}
a();
また、後で b を使用する他のコードがありますが、b は関数に対してローカルであるため、値は表示されません。もちろん、これの問題は、まだグローバル名を作成していることです。この場合は「a」です。したがって、名前のない関数が必要です。これが、説明したコードを取得する理由です。名前のない関数を宣言し、それを呼び出します。
残念ながら、次のように言うことはできません。
function() { ... }()
これは、関数宣言ステートメントとして解析され、構文エラーになるためです。関数宣言を括弧で囲むと、関数式が得られ、それを呼び出すことができます。2 番目の括弧のセットを使用して、他の関数式 (上記の a など) と同様に呼び出します。たとえば、関数が引数を取る場合は、そこに渡します。
(function(a) { ... })(1)
これにより、関数が作成され、呼び出され、破棄されます。
次のように見ると、より明確になる場合があります。
var throwaway = function(){
// do cool stuff
};
throwaway();
これは、プライベート名前空間を作成するために行われます。関数内のコードは、ページにロードされた他のコードとの競合を心配することなく、関数と変数を持つことができます。
その構造は、無名関数を宣言してすぐに実行することを意味します。コードを関数本体内に配置する理由は、内部で定義する変数がグローバル変数としてではなく、関数に対してローカルのままであるためです。ただし、この関数内で定義されたクロージャーには引き続き表示されます。
関数を囲む括弧は、関数が式であることを明確にします。後の括弧は関数の呼び出しです。
関数には名前がないことに注意してください。
クロージャーのアプローチの 1 つは、変数を関数に渡すことです。
(function($, var_1, var_2) {
// use JQuery, var_1 and var_2 as local variables
})($, var_1, var_2);
括弧内に関数宣言を置くと、その中の無名関数に評価される式が作成されます。したがって、最初のかっこは関数に評価されます。
最後の「空の括弧」は定義された関数を呼び出すため、「//do cool stuff」はすぐに実行されます。
これは、変数をグローバル スコープから除外しながら、オンザフライでコードを実行する方法です。
ただし、ここに示されていることは、クロージャーとは何の関係もありません - 少なくとも直接的には。クロージャーとは、親関数が既に終了した後にレキシカル スコープを維持することです。