首页 新闻 会员 周边

js的闭包也可能是延迟求值引发的问题?

0
悬赏园豆:20 [已解决问题] 解决于 2015-12-05 09:53

for(var i = 0; i< 10; i ++){

  var myBtn = new Button();

  myBtn.text = "should alert " + i.toString();

  myBtn.onclick = function(){

    alert(i);

  }

  myPnl.controls.add(myBtn);

}

随便一个例子说明问题,10个添加的按钮点击后弹出的都是9,而不是预期的12345....

求解

北在北方的主页 北在北方 | 初学一级 | 园豆:180
提问于:2015-12-04 17:20
< >
分享
最佳答案
0

这个是典型的闭包问题,解决方法如下:

myBtn.onclick = function(param_i){

  return function(){

          alert(param_i);

      } 

}(i);

具体为什么,你去探究下吧,那样才更有意思

 

-----------------------------第二次修改-------------------------------------

好像你就是来问为什么的,额……

既然说了闭包,那么就先要找到包

包在哪里(包是范围的意思,英文也就是scope)

请在chrome看scope值

第一个例子:

如果for(var i ;)……在顶层执行的话那么如果i在下文被用到的话,就会被存到 window中,也就是global的包中,也就是说 window.i=10;

包(变量)的逐层向上查找

当执行a[0].conclick()的时候,其实这个function中是没有i定义的,js就会往它的上层包中查找变量,自然就找到了global中,这个时候for循环已经完成了i已经变成10了,所以答案就是10了

顶层包与闭包

如果上层对象不是window那么,还会出现一个包,这个才是真正的闭包

 

对照着左边的代码,看右边的结果。

aArr[0].onclick()本身没有i变量,回去它的上层找找到了Closure包,那么自然找到了i=10。就是这样。(为啥person包中呢,因为js在执行的时候发现i被下层引用了,他就会自动存到闭包中)

如果下层没有引用那就不会存储了,毕竟是占空间的,还有坑引发内存无法释放问题

下图是不是不存储了

 

好了,给豆豆吧

收获园豆:20
SpringRen | 菜鸟二级 |园豆:412 | 2015-12-04 17:41

Thanks

北在北方 | 园豆:180 (初学一级) | 2015-12-05 09:53
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册