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

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

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

问题:

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

错误解法一:

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

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

错误解法二:

(所谓闭包)

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

解决方法二:

     for (var i =0 ; i<5 ; i++){
var btn = document.createElement("button");
!function(i){
btn.appendChild(document.createTextNode("Button"+i));
btn.addEventListener("click",function(){
console.log(i);
});
}(i);
document.body.appendChild(btn);
}
 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上,异曲同工之妙,都达到了中间值的保存。
 
上一篇:C++ 学习笔记 变量和基本类型(一)


下一篇:electron 使用中的注意事项