Javascript:闭包(クロージャ)

1つは、変数のスコープです。

クロージャを理解するには、最初にJavascriptの特別な変数スコープを理解する必要があります。

変数のスコープは、グローバル変数とローカル変数の2つのタイプにすぎません。

Javascript言語の特別な機能は、グローバル変数を関数内で直接読み取ることができることです。

  var n=999;
  function f1(){
    
    
    alert(n);
  }
  f1(); // 999

一方、関数内のローカル変数を関数外で読み取ることは当然不可能です。

 function f1(){
    
    
    var n=999;
  }
  alert(n); // error

ここで注意すべきことが1つあります。関数内で変数を宣言するときは、varコマンドを使用する必要があります。使用しない場合は、実際にグローバル変数を宣言します。

 function f1(){
    
    
    n=999;
  }
  f1();
  alert(n); // 999

第二に、外部からローカル変数を読み取る方法

さまざまな理由から、関数でローカル変数を取得する必要がある場合があります。ただし、前述のように、これは通常の状況では不可能であり、回避策によってのみ達成できます。

つまり、関数内に別の関数を定義することです。

  function f1(){
    
    
    var n=999;
    function f2(){
    
    
      alert(n); // 999
    }
  }

上記のコードでは、関数f 2 f2F 2は、関数に含まれている1つのF1 Ff 1の内部、この時点でf 1 f1内部のすべてのローカル変数F 1のために、F 2 F2両方のF 2が表示されています。しかし、その逆は機能しません、f 2 f2内部のローカル変数F 2のために、F 1 F1F 1は、目に見えないです。これは、Javascript言語の独自の「チェーンスコープ」構造です。子オブジェクトは、親オブジェクトのすべての変数をレベルごとに検索します。したがって、親オブジェクトのすべての変数が子オブジェクトに表示され、その逆も同様です。

f 2f2以降F 2読むことができる1つのF1 fはf 1にローカル変数を入力し、 f 2f2を入力します。f 2が戻り値として使用されるため、f 1f1を使用できます。f 1はその内部変数を外部から読み取っています!

 function f1(){
    
    
    var n=999;
    function f2(){
    
    
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999

三、閉鎖の概念

前のセクションのコードのF2 f2F 2関数はクロージャです。クロージャは、他の関数の内部変数を読み取ることができる関数です。

Javascript言語では、関数内のサブ関数のみがローカル変数を読み取ることができるため、クロージャーは単に「関数内で定義された関数」として理解できます。

したがって、本質的に、クロージャは関数の内側と関数の外側を接続するブリッジです。

第四に、クロージャの使用

クロージャーは多くの場所で使用できます。それには2つの最大の用途があります。

  • 1つは、関数内で読み取ることができる前述の変数です。
  • もう1つは、これらの変数の値をメモリに保持することです。
 function f1(){
    
    
    var n=999;
    nAdd=function(){
    
    n+=1}
    function f2(){
    
    
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
  nAdd();
  result(); // 1000

このコードでは、結果は実際にはクロージャーf 2f2です。F 2機能。2回実行され、1回目は999で、2回目は1000でした。これは、関数f 1f1がローカル変数NNでF 1nf1 f1ではなく、メモリに保持されていますf 1が呼び出されると、自動的にクリアされます。

なぜそうなのですか?その理由は、f 1 f1F 1は、ある2 F2 fはF 2親関数、およびf 2 f2f 2はグローバル変数に割り当てられ、その結果f 2f2になります。f 2は常にメモリ内にあり、f 2 f2存在F 2が依存する1つのF1 Ff 1つまりf 1 f1f 1は常にメモリ内にあり、呼び出しの終了後にガベージコレクションメカニズムによって収集されることはありません。

このコードのもう1つの注目すべき場所は、「nAdd = function(){n + = 1}」という行です。まず、varキーワードはnAddの前に使用されないため、nAddはローカル変数ではなくグローバル変数です。次に、nAddの値は無名関数であり、無名関数自体もクロージャであるため、nAddは、関数外の関数内のローカル変数を操作できるセッターと同等です。

5、クロージャーを使用する際の注意点

クロージャによって関数内の変数がメモリに格納されるため、クロージャは大量のメモリを消費する外部ローカル変数の破壊を防ぎます。したがって、クロージャを悪用しないでください。悪用しないと、Webページでパフォーマンスの問題が発生します。 IEメモリリークで問題が発生する可能性があります。解決策は、関数を終了する前に、未使用のローカル変数をすべて削除することです。

クロージャーは親関数の外側にあり、親関数の内側の変数の値を変更します。したがって、親関数をオブジェクトとして、クロージャをパブリックメソッドとして、内部変数をプライベート値として使用する場合は、この時点で注意する必要があります。親関数の内部変数の値は自由に変更してください。 。

おすすめ

転載: blog.csdn.net/u013250861/article/details/113622140