クローズドの利用によるクローズド保存状態

1641 ワード

前言
まず、ここではクローズドバッグについて理解したいですが、ここでは詳しく紹介しません.
以下のコードを見てください
  
     
     
     
 var button = document.getElementsByTagName("button");

    var addEventListener = function(nodes){
        var i;

        for(i = 0; i < nodes.length; i++){
            nodes[i].onclick = function(e){
                alert(i);
            }
        }
    }

    addEventListener(button);
ここの運行結果はどうなりますか?結果は:buttonをクリックするごとに、最後にalertのは2です.
forサイクルの時は、単にbuttonにバインディングされたイベントだけが、buttonをクリックすると、対応するイベントが実行されます.alert現在iの値があります.jsでは、関数は定義されたスコープの中で実行されます.一つの関数が別の関数の中で定義されている限り、この関数はその所在関数で定義されているすべての変数にアクセスできます.ここの関数は、addeventlistenerの中で定義されています.onclickイベントを実行すると、forサイクルが完了し、関数のiはすでに2になりました.だから、どのbuttonをクリックしても、alertのは2です.
クローズドによる保存状態
以下のコードを見てください
var button = document.getElementsByTagName("button");
    //    
    var addEventListener = function(nodes){
        var helper = function(i){
            return function(e){
                alert(i);
            };
        };

        var i;

        for(i = 0; i < nodes.length; i++){
            nodes[i].onclick = helper(i);
        }
    }

    addEventListener(button);
上のforサイクルの中で、サイクルごとに1回、リアルタイムのiをhelperに伝えて、buttonをクリックする時、alert(i)のこの関数はhelperの中で定義されているので、iもhelperから来ています.だから、毎回iを遍歴した状態を保存することができます.上から見て、
関数がhelper内に定義されている限り、helper内に定義されているすべての変数にアクセスできます.helperがすでに実行されていても.
また、クローズドは直接returnの関数ですので、returnのこの関数はグローバル呼び出しに相当します.その中の変数はずっとメモリに保存されます.
参考文献:http://www.yuanlairc.com/program/closure.html