由于js词法性质和全局变量被更改,循环绑定的click事件执行时变量和定义时 不一致的bug,各种解决方案。...

由于js词法性质和全局变量被更改,循环绑定的click事件执行时变量和定义时 不一致的bug,各种解决方案。

动态在页面上添加了5个按钮,实现的功能应该是点击对应按钮在控制台输出相应的索引。但因为应该是i的变量应该一直指引的对应的地址,所以一直输出的是5.就是想请教您一下,这种问题应该是怎么样的一个解决思路。您要是有时间的时候帮我看下。非常感谢!

问题:

1 //这个有bug,一直输出5
2 for (var i =0 ; i<5 ; i++){
3 var btn = document.createElement("button");
4 btn.appendChild(document.createTextNode("Button"+i));
5 btn.addEventListener("click",function(){
6 console.log(i);
7 });
8 document.body.appendChild(btn);
9 }

错误解法一:

(虽然定义了新变量 ,避免了使用全局的i,但是,新变量一直被重新定义,最终定义为和最新的i保持一样了 )

 1     for (var i =0 ; i<5 ; i++){
 2     var btn = document.createElement("button");
 3     btn.appendChild(document.createTextNode("Button"+i));var j=i;
 4     btn.addEventListener("click",function(){
 5         console.log(j);
 6     });
 7     document.body.appendChild(btn);
 8 }
 9
10 //一直输出4

 错误解法二:

(所谓闭包)

 1 for (var i =0 ; i<5 ; i++){
 2     var btn = document.createElement("button");
 3     btn.appendChild(document.createTextNode("Button"+i));
 4     btn.addEventListener("click",function(){
 5         var result = function (num){
 6             return function(){
 7                 return num;
 8             }
 9         }(i);
10         console.log(result);
11     }
12     );
13     document.body.appendChild(btn);
14 }

 

解决方法一:
1 for (var i =0 ; i<5 ; i++){
2     var btn = document.createElement("button");
3     btn.appendChild(document.createTextNode("Button"+i));
4         btn.id="btn_"+i;
5     btn.addEventListener("click",function(){
6         console.log(this.id.split("_")[1]);
7     });
8     document.body.appendChild(btn);
9 }

解决方法二:

 1     for (var i =0 ; i<5 ; i++){
 2     var btn = document.createElement("button");
 3     !function(i){
 4     btn.appendChild(document.createTextNode("Button"+i));
 5     btn.addEventListener("click",function(){
 6         console.log(i);
 7     });
 8 }(i);
 9     document.body.appendChild(btn);
10 }

 1     for (var i =0 ; i<5 ; i++){
 2     var btn = document.createElement("button");
 3     (function(i){
 4     btn.appendChild(document.createTextNode("Button"+i));
 5     btn.addEventListener("click",function(){
 6  console.log(i); 7  }); 8 })(i); 9  document.body.appendChild(btn); 10 }

 总结:

 两种闭包方案,为何一个错,一个对?

 虽然都是闭包,但是你的没有把需要的东西给关闭进去,因为你的范围太小,你关时,人家已经是5 了。
 
两种正确做法有何区别?
而他们的写法是,在没成5时,就关闭进去,这样就保护了变量的中间值,他们存在闭包内,而另一种存在dom上,异曲同工之妙,都达到了中间值的保存。
 

转载于:https://www.cnblogs.com/ecmasea/p/5952909.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值