JS のクロージャを理解するために、CET-4 の英語スキルを使って Google でクロージャに関する説明を検索したときに、中国には人々を教えたり教育したりする雰囲気がないとますます感じています。答えを返した後、次のような一文が頭に浮かびました。だからコイツは逃げなかったのです
訳は以下です、面白いです。
ピーター・モーテンセンはこう尋ねました。
アルバート老人が言ったように、「6 歳の子供に説明できないのは、あなた自身が理解していないということです。」 27歳の友人にJSクロージャ(JavaScriptクロージャ)について教えようとしたのですが、完全に失敗しました。
好奇心旺盛な 6 歳児にこれをどう説明しますか?
注: StackOverflow で提供されている例を見ましたが、まったく機能しませんでした。
アリの答え:
関数が関数内にネストされている場合、内側の関数は外側の関数の変数にアクセスできます。
function foo(x) {
var tmp = 3;
関数 bar(y) {
alert(x y ( tmp));
bar(10);
foo(2); >
bar は foo のパラメータ x と foo の変数 tmp にアクセスできるため、何度実行してもアラート 16 が発行されます。
ただし、これはまだ終了ではありません。内部関数を返す場合、それはクロージャです。内部関数は、内部関数が終了するまで外部関数の変数をクローズオーバーします。
var tmp = 3;
return function (y) {
alert(x y ( tmp));
}
} // bar = foo(2); close
bar(10);
bar は foo の内部スコープに直接含まれていませんが、bar は依然として x と tmp にアクセスできるため、上記のスクリプトは最終的に 16 を警告します。
ただし、tmp は bar を持つクロージャ内にまだ存在するため、1 ずつ増加し、bar を呼び出すたびに 1 ずつ増加します (この制限を 6 つ考慮します。実際には、配列を返す、またはそれらをグローバル変数として設定するなど、複数のクロージャー メソッドを作成できます (それぞれがコピーを持つのではなく)。
注:さて、7年前のコンテンツについて話しましょう。
上記の x はリテラル値 (値の転送) であり、JS の他のリテラル値と同様に、foo が呼び出されるときに、実パラメータ x の値がコピーされ、コピーされたコピーがとして使用されます。 foo のパラメータ x。
問題は、JS でオブジェクトを処理するときに参照が使用されるため、foo を呼び出してオブジェクトを渡すと、foo 関数によって返されるクロージャも元のオブジェクトを参照することになります。 🎜>
コードをコピーします
コードは次のとおりです。
}
}
var age = new Number(2);
var bar = foo(age); // bar は age
bar(10); 🎜>
予想通り、x.memb は bar(10) が実行されるたびに 1 ずつ増加します。ただし、x は同じオブジェクト変数 age を指していることに注意してください。bar(10) を 2 回実行すると、age.memb は 2 になります。
これは、HTML オブジェクトのメモリ リークに関連しています。ああ、しかしそれは質問に答える範囲を超えているようです。
JohnMerlino は Ali にこう言いました:
これは return キーワードのないクロージャの例です:
コードをコピーしてください
コードは次のとおりです。
function ClosureExample(obj, text, timelay) {
setTimeout(function() { document.getElementById(objID).innerHTML = テキスト; }, 時間遅延); } closureExample('myDiv', 'クロージャが作成されました', 500);
深夜 1:37 John Pick は次のように答えました:
JS 内の関数は次のようにアクセスできます:
1. パラメーター
2. ローカル変数または関数
3.
を含む外部変数 (環境変数?) 3.1 DOM を含むグローバル変数
3.2 外部関数の変数または関数。
関数が外部変数にアクセスする場合、それはクロージャです。
外部関数は必要ないことに注意してください。外部変数にアクセスすることで、クロージャはこれらの変数を生きたままにしておくことができます。内部関数と外部関数の場合、外部関数はローカル変数を作成して最終的に終了できますが、終了後に 1 つ以上の内部関数が終了しない場合、内部関数は外部関数のローカル データを維持します。
典型的な例は、グローバル変数の使用です。
mykhal は次のように答えました:
Wikipedia ではクロージャを次のように定義しています:
コンピュータ サイエンスでは、クロージャは非ローカル名 (自由変数) の参照環境を備えた関数です。
厳密に言えば、JS では、すべての関数はその外部で定義されたデータに常にアクセスできるため、クロージャです。
JavaScript のスコープ定義構造は関数であり、他の多くの言語のようなコード ブロックではないため、通常、JavaScript でクロージャが意味するものは、すでに実行された周囲の関数で定義された非ローカル変数を操作する関数です。
クロージャは、非表示のデータを含む関数を作成するためによく使用されます (常にではありません)。
var db = (function() {
/ / 隠しオブジェクトを作成します。このオブジェクトはデータを保持します。
// このオブジェクトは外部からアクセスできません。
var data = {}
// 関数を作成します。この関数は何らかのアクセスを提供します。 to data データメソッド
return function(key, val) {
if (val === unknown) { return data[key] } // get
else { return data[key] = val } // set
}
// この匿名メソッドを呼び出すことができます
// クロージャであるこの内部関数を返します
})()(); // Return unknown
db('x', 1); // data['x'] を 1 に設定します
db('x'); // Return 1
// にアクセスできませんデータオブジェクト自体
// しかし、そのメンバーを設定することはできます
海外の専門家からの多くの回答を読んだ後、理解しているかどうかはわかりませんが、とにかく理解しました。