浅谈JavaScript for循环 闭包

有个网友问了个问题,如下的html,为什么每次输出都是5,而不是点击每个p,就alert出对应的1,2,3,4,5。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
< 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)上

?
1
2
3
4
5
6
7
8
9
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 保存在匿名函数自身

?
1
2
3
4
5
6
7
8
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、加一层闭包,i以函数参数形式传递给内层函数

?
1
2
3
4
5
6
7
8
9
10
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以局部变量形式传递给内存函数

?
1
2
3
4
5
6
7
8
9
10
11
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的细微区别)

?
1
2
3
4
5
6
7
8
9
10
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实现,实际上每产生一个函数实例就会产生一个闭包

?
1
2
3
4
5
6
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的区别

?
1
2
3
4
5
6
function init7() {  
   var pAry = document.getElementsByTagName( "p" );  
   for ( var i=0; i<pAry.length; i++ ) {  
      pAry[i].onclick = Function( 'alert(' +i+ ')'
   }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值