閉じて小記を勉強します
4156 ワード
参考:JavaScript高級プログラム設計(第2版)第4章-スコープと第7章-匿名関数
クローズドを明らかにする前に、まず実行環境とスコープを簡単に調べてみます.各実行環境には変数オブジェクトがあります.環境で定義されているすべての変数と関数はこのオブジェクトに保存されます.グローバル実行環境は最も周辺の実行環境であり、WEBブラウザではwindowオブジェクトとして認識されている.実行環境にあるすべてのコードが実行された後、この環境は破壊され、保存されているすべての変数と関数の定義も破壊され、アプリケーションが終了するまでグローバル実行環境は破壊されます.各関数は呼び出し時に自分の実行環境と対応する作用ドメインチェーンを作成し、その作用ドメインチェーンを内部属性に割り当てます.コードが一つの環境で実行されると、変数オブジェクトから構成されるロールドメインチェーンが作成され、作用ドメインチェーンは、実行環境にアクセスできるすべての変数と関数に対して規則的なアクセスを保証します.スコープの先端は、常に現在実行されているコードがある環境の変数オブジェクトです.この環境が関数である場合、そのアクティブオブジェクトを変数オブジェクトとします. スコープ内の次の変数オブジェクトは、その外部環境を含めてグローバル実行環境に至るまで、グローバル実行環境の変数オブジェクトは常にスコープ内の最後のオブジェクトとして機能します. 識別子解析時に、スコープの一級に沿って、端から順に識別子を検索します.識別子が見つかるまで.
スコープは、本質的には変数オブジェクトを指すポインタのリストです.変数オブジェクトは参照だけですが、実際には含まれていません.javascriptでは、括弧で閉じられたコードブロックは、自分の役割領域である実行環境ではありません.以上は環境と作用領域を実行するいくつかの基本的な知識であり、現在はクローズドを参照してください.クローズドとは、他の関数の作用領域にアクセスできる変数の関数です.二つの例を見てみます.例1:
クローズドを明らかにする前に、まず実行環境とスコープを簡単に調べてみます.各実行環境には変数オブジェクトがあります.環境で定義されているすべての変数と関数はこのオブジェクトに保存されます.グローバル実行環境は最も周辺の実行環境であり、WEBブラウザではwindowオブジェクトとして認識されている.実行環境にあるすべてのコードが実行された後、この環境は破壊され、保存されているすべての変数と関数の定義も破壊され、アプリケーションが終了するまでグローバル実行環境は破壊されます.各関数は呼び出し時に自分の実行環境と対応する作用ドメインチェーンを作成し、その作用ドメインチェーンを内部属性に割り当てます.コードが一つの環境で実行されると、変数オブジェクトから構成されるロールドメインチェーンが作成され、作用ドメインチェーンは、実行環境にアクセスできるすべての変数と関数に対して規則的なアクセスを保証します.スコープの先端は、常に現在実行されているコードがある環境の変数オブジェクトです.この環境が関数である場合、そのアクティブオブジェクトを変数オブジェクトとします. スコープ内の次の変数オブジェクトは、その外部環境を含めてグローバル実行環境に至るまで、グローバル実行環境の変数オブジェクトは常にスコープ内の最後のオブジェクトとして機能します. 識別子解析時に、スコープの一級に沿って、端から順に識別子を検索します.識別子が見つかるまで.
スコープは、本質的には変数オブジェクトを指すポインタのリストです.変数オブジェクトは参照だけですが、実際には含まれていません.javascriptでは、括弧で閉じられたコードブロックは、自分の役割領域である実行環境ではありません.以上は環境と作用領域を実行するいくつかの基本的な知識であり、現在はクローズドを参照してください.クローズドとは、他の関数の作用領域にアクセスできる変数の関数です.二つの例を見てみます.例1:
function apple (){
var num = 10;
return function (){
alert(num--);
}
}
apple()(); //10
apple()(); //10
apple()(); //10
例2:function apple (){
var num = 10;
return function (){
alert(num--);
}
}
var showNum = apple();
showNum(); //10
showNum(); //9
showNum(); //8
上記の例では、匿名関数は外部関数apple()の変数numにアクセスし、リターンされ、グローバル実行環境で呼び出された後もnumにアクセスできます.これは、匿名関数が呼び出されると、そのために作成されたスコープにapple()という関数のスコープが含まれているので、作用領域チェーンに沿ってnum変数を検索することができるからである.例1において、apple()()は、何回実行しても10であり、例2においてshowNum()は、ポップアップ値を呼び出すたびに減少する.これは、関数の実行が完了すると、部分的な活動オブジェクトが破壊され、メモリには大域的な作用領域のみが保存されるからです.例1はこのように、apple()が実行されるたびに、匿名関数の作用ドメインチェーンが破壊され、apple()関数のすべての変数が破壊され、再びapple()を実行すると、訪問したのは常に初期値が10のnumである.しかし、例2の場合は異なるが、戻った匿名関数は変数showNumに割り当てられ、apple()が実行された後も、その活動対象は破棄されない.匿名関数の作用領域チェーンは、匿名関数が破壊されるまで、この活動対象を参照しているからである.例えば、showNum=nullを設定し、匿名関数の参照を解除し、匿名関数の作用領域チェーンが破壊されると、その他の作用領域(グローバルスコープを除く)は安全に廃棄されます.注意すべき問題があります.クローズドは関数内の変数を含む最後の値しか取得できません.例3:function createFunction(){
var fun = new Array();
for (var i =0;i<10;i++){
fun[i] = function(){
alert(i);
};
}
return fun;
}
var fun = createFunction();
for(i=0;i<fun.length;i++){
fun[i](); //10
}
この例では、fun[i]()が実行されるたびに、ポップアップ値は10である.これは、createFunction()という関数を実行した後、iの最終値が10であり、その後、匿名関数を呼び出してそのためにスコープを作成するたびに、参照される外部変数オブジェクトのiの値が10であるためである.