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);
    }
}
经验分享 程序员 微信小程序 职场和发展