1。変数の範囲
閉鎖を理解するには、最初にJavaScriptの特別な変数範囲を理解する必要があります。
変数には、グローバル変数とローカル変数の2種類のスコープのみがあります。
JavaScript言語の特別な特徴は、グローバル変数を関数内で直接読み取ることができることです。
var n = 999;関数f1(){alert(n); } f1(); // 999一方、関数内のローカル変数は、当然関数の外側で読み取られません。
関数f1(){var n = 999; }アラート(n); // エラーここに注意する場所があります。変数を内部的に宣言する場合は、VARコマンドを使用する必要があります。そうでない場合は、実際にグローバル変数を宣言します!
関数f1(){n = 999; } f1();アラート(n); // 9992。外部からローカル変数を読む方法は?
さまざまな理由で、関数内でローカル変数を取得する必要がある場合があります。ただし、前述のように、通常の状況では、これは実行できず、回避策によってのみ達成できます。
それは、関数内の別の関数を定義することです。
関数f1(){var n = 999; function f2(){alert(n); // 999}}上記のコードでは、関数F2が関数F1内に含まれており、F1内のすべての局所変数がF2に表示されます。しかし、逆の方法は不可能です。 F2内のローカル変数は、F1には見えません。これは、JavaScript言語に固有の「チェーンスコープ」構造です。子オブジェクトは、すべての親オブジェクト変数のレベルごとに上向きに見えます。したがって、親オブジェクトのすべての変数が子オブジェクトに表示されます。そうしないと、それは真ではありません。
F2がF1のローカル変数を読み取ることができるため、F2が戻り値として使用される限り、F1以外の内部変数を読むことはできませんか?
関数f1(){var n = 999; function f2(){alert(n); } f2を返します。 } var result = f1();結果(); // 9993。閉鎖の概念
コードの前のセクションのF2関数は閉鎖です。
さまざまな専門文書における「閉鎖」の定義は非常に抽象的で理解が困難です。私の理解では、閉鎖は他の関数内の変数を読み取ることができる関数であるということです。
JavaScript言語では、関数内のサブファクションのみがローカル変数を読み取ることができるため、閉鎖は「関数内で定義された関数」として簡単に理解できます。
したがって、本質的に、閉鎖とは、関数の内側と外側を結ぶブリッジです。
4。閉鎖の目的
閉鎖は多くの場所で使用できます。 2つの最大の用途があります。1つは、関数内の変数を上記のように読み取ることができ、もう1つはこれらの変数の値が常にメモリに保持されることです。
この文を理解する方法は?以下のコードをご覧ください。
関数f1(){var n = 999; nadd = function(){n+= 1} function f2(){alert(n); } f2を返します。 } var result = f1();結果(); // 999 NADD();結果(); // 1000このコードでは、結果は実際には閉鎖F2関数です。合計で2回実行され、最初の値は999、2番目の値は1000です。これは、関数F1のローカル変数nがメモリに保持され、F1が呼び出された後に自動的にクリアされないことを証明しています。
なぜこれが起こっているのですか?その理由は、F1がF2の親機能であり、F2がグローバル変数に割り当てられ、F2が常にメモリになり、F2の存在はF1に依存するためです。したがって、F1は常にメモリにあり、コールが終了した後、ゴミ収集メカニズムによってリサイクルされません。
このコードのもう1つの注目すべき点は、「nadd = function(){n+= 1}」という行が最初にNADDの前に使用されるため、NADDはローカル変数ではなくグローバル変数であることです。第二に、NADDの値は匿名関数であり、この匿名関数自体も閉鎖であるため、NADDは関数の外側の関数内のローカル変数で動作するセッターと同等です。
5。閉鎖の使用に関するメモ
1)閉鎖は関数のすべての変数をメモリに保存し、メモリ消費量が非常に大きく、閉鎖は乱用できないため、Webページのパフォーマンスの問題を引き起こし、IEでメモリ漏れにつながる可能性があります。解決策は、関数を終了する前に使用されないすべてのローカル変数を削除することです。
2)閉鎖により、親関数の外側の親関数内の変数の値が変更されます。したがって、親関数をオブジェクトとして使用する場合、クロージャーをパブリックメソッドとして使用し、内部変数を私有地として使用します。親関数の内部変数の値をWELで変更しないように注意してください。