js for循环点击事件输出i的值错误的原因
例如:
var lis = document.querySelector(.nav).querySelectorAll(li);
for(var i = 0;i<lis.length;i++){
lis[i].onclick = function (){
console.log(i);
}
}
结果:点击事件输出的 i 的值始终是4。
原因:
在每个点击事件函数的作用域链中都保存着windows的活动对象(for语句不构成作用域),所以它们引用的是同一个变量i,即i属于一个全局变量,所以在给每个li绑定事件后,每个函数内部i的值都是4。
通俗点说:先给每个li绑定点击事件,绑定完点击事件后,i变为4。i是一个全局变量,所以再点击某个li输出i的时候,输出的自然是4了。
解决方法: (1)过创建另一个匿名函数强制让闭包的行为符合预期
for(var i = 0;i<lis.length;i++){
//利用for循环创建4个立即执行函数
(function (num){
lis[num].onclick = function(){
console.log(num);
}
})(i)
}
定义了一个匿名函数,这里的匿名函数有一个参数 num,也就是最终的函数要输出的值。在调用每个匿名函数时,我们传入了变量 i。由于函数参数是按值传递的,所以就会将变量 i 的当前值复制给参数 num。这样一来,li每个函数都有自己 num 变量的一个副本,因此就可以返回各自不同的数值了。
(2)给每个li添加一个Index属性来记录i值
for(var i = 0;i<lis.length;i++){
lis[i].setAttribute(index,i) ;
lis[i].onclick = function (){
console.log(this.getAttribute(index));
}
}
(3)使用es6 中的let关键字
var lis = document.querySelector(.nav).querySelectorAll(li);
for(let i = 0;i<lis.length;i++){
lis[i].onclick = function (){
console.log(i);
}
}
