闭包,小考题

三个按钮,希望点击第一个按钮显示 0,第二个按钮显示 1,第三个按钮显示 2。怎么做呢?

<input  type="button"  id="b0"  value="0"  />
<input  type="button"  id="b1"  value="1"  />
<input  type="button"  id="b2"  value="2"  />

<script  type="text/javascript"  src="http://www.cftea.com/js/ezj_v2.9/ezj.js" > </script >
<script  type="text/javascript" >
<!--
for ( var i = 0; i < 3; i++)
{
    $( "b" + i). click( function(){
         alert(i);
    });
}
//-->
</script >

以上代码是错误的,因为不论点哪个按钮,都是显示 3。

这是由于 i 经过 for 循环后,变成了 3,再点击按钮,始终用的是 i 的最终值,那如下代码是不是正确了呢?

for ( var i = 0; i < 3; i++)
{
     var m = i;
    $( "b" + i). click( function(){
         alert(m);
    });
}

也不对,这个闭包的 m 在 alert 所处的 function 之外,也就是说不受 function 保护,仍会受到 for 循环的改变,function() 中的 m 值永远是外层 m 的最后值,点任何一个按钮都会显示 2(i 在循环内的最后值)。

正确的做法

for ( var i = 0; i < 3; i++)
{
    ( function(i){
        $( "b" + i). click( function(){
             alert(i);
        })
    })(i);
}

// 等效于下面的:

for ( var i = 0; i < 3; i++) 

     function f(i)
    { 
        $( "b" + i). click( function(){ 
             alert(i); 
        }) 
    }
    f(i);
}

注意 function(i) 中的 i 不能省略,否则 alert(i) 仍然是 for 循环的 i。

另外还有一种方法,和上面的代码是一个道理,不过是借助了 ezj 中,click 可以向事件处理程序传送 DOM 对象的原理,我们可以发现 click 中的 function() 变成了 function(e)

for ( var i = 0; i < 3; i++)
{
     var b = $( "b" + i);
    b.alertText = i;
    b. click( function(e){
         alert(e.alertText);
    });
}

备注: ------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------
简言之,闭包是产生一个没有被释放资源的栈区。换言之,就是一个不可控的内存空间占用,如果与事件相关联,JS的垃圾回收机制也不会去触碰该区域。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值