JavaScript N種閉包演示

jiestyle21發表於2011-09-27

先說說什麼是閉包,我就用通俗易懂的語言來描述一下什麼是閉包。

閉包,其實就是指程式語言中能讓程式碼呼叫已執行的函式中所定義的區域性變數。明瞭不?還不懂?不懂百度去吧。

有個網友問了個問題,如下的html,為什麼每次輸出都是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、將變數 i 儲存給在每個段落物件(p)上

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+')')
    } 
} 
轉於:http://snandy.iteye.com/blog/250073












相關文章