JavaScript----クローズド

3891 ワード

javascriptの閉鎖
クローズドの概念
   クローズドはJavaScriptの文法的特性です.
クローズドはコードブロックとコードブロックを作成するコンテキスト(環境)におけるデータとの結合である.
   クローズドとは関数の内部定義関数であり、内部の関数はその外部関数の作用領域にアクセスすることができます.以下は、プログラムにおいて、クローズドを実現する例である.
   クローズドとは、別の関数の作用領域にアクセスできる変数の関数です.(Javascript高級プログラミングP 178)
function outer(name){ //      

 var msg="hello";
  function inner(){ //     
   alert(msg+" "+name);
  }
  return inner(); //       
 }
 var clos=outer("WANGERN");
 clos();
実行コードは、「hello WANGERN」と警告します.
前提
    はクローズドを理解するために、もう一つの重要な概念であるJavaScriptの作用領域規則があります.まず、スコープを説明します.実行関数では、関数に属するコンテキスト環境およびスコープを作成します.スコープは現在の環境範囲の変数です.JavaScriptの中で最も周辺の環境はwindowオブジェクト、つまりグローバルスコープがある環境です.次のレベルの環境に実行すると、次のレベルの環境は、積極的に前のレベルの作用ドメインを含み、最終的には一級レベルの関連する作用ドメインチェーン(対象の「Scope」属性がこの作用ドメインチェーンを指す)を形成する.次の環境が生成されると、前のレベルの環境は失われますが、自動的に破壊されずに「スタック」式の構造に保存されます.これにより、作用ドメインチェーンの継続性が保証され、環境が後退すると再び活性化されます.現在の環境は、上のコードのinner関数などの現在のスコープチェーンのすべての変数にアクセスできます.outer()関数のmsgとname変数にアクセスできます.
   閉包はこのような作用領域チェーンによって内部関数が外部関数にアクセスできる変数です.一方、クローズドは、外部関数環境の破壊を抑制し、不要なときに破壊するまでその変数を常にメモリに保存します.
クローズドの例
    はまず以下の例を見て、functionにfunctionを入れ込むと、内部のfunctionは外部function内の変数にアクセスすることができます.
function foo(x) {
    var tmp = 3;
    function bar(y) {
        alert(x + y + (++tmp));
    }
    bar(10);
}
foo(2)
何回実行してもalert 16は、barがfooのパラメータxにアクセスできるので、fooの変数tmpにもアクセスできます.
しかし、これはまだ閉鎖されていません.あなたがreturnのが内部のfunctionな時、ひとつが閉じます.内部functionでは、内部functionが終了するまでクローズ-over外部functionの変数が使用されます.
function foo(x) {
    var tmp = 3;
    return function (y) {
        alert(x + y + (++tmp));
    }
}
var bar = foo(2); // bar        
bar(10);
上のスクリプトも最終的にalert 16になります.barは直接fooの内部作用域にはありませんが、barはxとtmpにアクセスできます.
    しかし、mpは依然としてbarの閉鎖された内部に存在するので、それはやはり1をプラスします.また、barを呼び出すたびに1をプラスします.
    (私たちは実際には、returnのようなそれらの配列を大域変数に設定することもできます.それらはすべて同じxと同じtmpを指しています.それぞれがコピーを持っているのではありません.)
    上のxは一文字の面の値であり、JS内の他の面の値と同じで、fooを呼び出すと、実参xの値が一部コピーされ、コピーされた分はfooのパラメータxとして作用します.
  JSでobjectを処理する時は引用伝達に使います.fooを呼び出したらobjectを伝えます.foo関数returnのクローズドも最初のobjectを参照してください.
function foo(x) {
var tmp = 3;
return function (y) {
    alert(x + y + tmp);
    x.memb = x.memb ? x.memb + 1 : 1;
    alert(x.memb);
    }
}
var age = new Number(2);
var bar = foo(age); // bar         age   
bar(10);
私達は予想できません.bar(10)を運行しています.x.membは1を追加します.ただし、xは毎回同じobject変数——ageを指し、2回bar(10)を実行すると、age.membは2.
これはHTMLオブジェクトのメモリ漏れと関係がありますが、えっと、解答の範囲を超えているようです.
    ここにreturnキーワードを使わないクローズドの例があります.
function closureExample(objID, text, timedelay) {
    setTimeout(function() {
        document.getElementById(objID).innerHTML = text;
    }, timedelay);
}
closureExample(‘myDiv’, ‘Closure is created’, 500);
  JSのfunctionはそれらのものにアクセスできます.
  • パラメータ
  • 局所変数または関数
  • 外部変数(環境変数)は、DOMを含む3.1グローバル変数を含む.3.2外部関数の変数または関数.
  •     関数が外部変数にアクセスしたら、それは閉じられています.
    外部関数は必須ではないので注意してください.外部変数にアクセスすることで、これらの変数を維持することができます.内部関数と外部関数の例では、外部関数は局所変数を作成し、最終的に終了します.しかし、任意の内部関数が終了しても終了しない場合、内部関数は外部関数の局所データを維持する.
    典型的な例はグローバル変数の使用です.
        は技術的にはJSではFunctionごとにクローズドされています.
       クローズドは、常に隠しデータを含む関数を作成するために使用されます.
    var db = (function() {
    //        object,   object      
    //           object 
    var data = {};
    //       ,           data      
    return function(key, val) {
        if (val === undefined) { return data[key] } // get
        else { return data[key] = val } // set
        }
    //             
    //         ,      
    })();
    
    db('x'); //    undefined
    db('x', 1); //   data['x'] 1
    db('x'); //    1
    //        data  object  
    //             
    
    閉包のまとめ
    閉包はコンテキストを分析することによって、ユーザの呼び出しを簡略化し、ユーザーが知らない状況で、彼の目的を達成するようにする設計原則である.ネット上で主流のクローズド分析に対する文章は実はクローズド原則と逆方向に走っています.もしクローズドの詳細を知る必要があれば、このクローズドは設計に失敗します.   (3)はクローズドがその関数を含む作用域を運ぶため、他の関数よりも多くのメモリを占有します.クローズドを使いすぎるとメモリの占有が多すぎるかもしれません.