JavaScriptはクローズドしてfor循環i【回転】を取ります.


あるネット友達が聞きましたが、以下のように)、どうして毎回出力は5で、各pをクリックするのではなく、alertに対応する1、2、3、4、5を出しますか?
    <html >   
    <head>   
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />   
    <title>    </title>   
    <script type="text/javascript">   
      
    function init() {   
        var pAry = document.getElementsByTagName("p");   
        for( var i=0; i<pAry.length; i++ ) {   
             pAry[i].onclick = function() {   
             alert(i);   
        }   
      }   
    }   
    </script>   
    </head>   
    <body onload="init();">   
    <p>   </p>   
    <p>   </p>   
    <p>   </p>   
    <p>   </p>   
    <p>   </p>   
    </body>   
    </html>   
 
解決方法は二つあります.
1、各段落オブジェクト(p)に変数iを保存します.
    function init() {   
      var pAry = document.getElementsByTagName("p");   
      for( var i=0; i<pAry.length; i++ ) {   
         pAry[i].i = i;   
         pAry[i].onclick = function() {   
            alert(this.i);   
         }   
      }   
    }   
 
2、変数iを匿名関数自体に保存する 
    function init2() {   
      var pAry = document.getElementsByTagName("p");   
      for( var i=0; i<pAry.length; i++ ) {     
       (pAry[i].onclick = function() {   
            alert(arguments.callee.i);   
        }).i = i;   
      }   
    }   
さらに3種類追加します
 
3、一層のクローズドを加えて、iは関数パラメータ形式で内層関数に伝達する.
    function init3() {   
      var pAry = document.getElementsByTagName("p");   
      for( var i=0; i<pAry.length; i++ ) {   
       (function(arg){       
           pAry[i].onclick = function() {       
              alert(arg);   
           };   
       })(i);//        
      }   
    }   
 
4、一層のクローズドを追加し、iは局所変数形式でメモリ関数に伝達する.
    function init4() {   
      var pAry = document.getElementsByTagName("p");   
      for( var i=0; i<pAry.length; i++ ) {     
        (function () {   
          var temp = i;//          
          pAry[i].onclick = function() {     
            alert(temp);     
          }   
        })();   
      }   
    }   
5、クラッチを入れて、応答イベントとして関数を返します(3との微妙な違いに注意してください)
    function init5() {   
      var pAry = document.getElementsByTagName("p");   
      for( var i=0; i<pAry.length; i++ ) {     
       pAry[i].onclick = function(arg) {   
           return function() {//         
           alert(arg);   
         }   
       }(i);   
      }   
    }  
 
もう一つの方法があります
 
 
6、Functionで実装されていますが、実際には関数のインスタンスを生成するごとに一つのクローズドが発生します.
    function init6() {   
        var pAry = document.getElementsByTagName("p");   
        for( var i=0; i<pAry.length; i++ ) {     
          pAry[i].onclick = new Function("alert(" + i + ");");//new             
        }   
    }  
 
もう一つ追加します
7、Functionで実現し、6との違いに注意する.
function init7() {   
    var pAry = document.getElementsByTagName("p");   
    for( var i=0; i<pAry.length; i++ ) {   
         pAry[i].onclick = Function('alert('+i+')')  
    }