js for循环中点击事件中无法获取每一个i值的问题

好像是第二次遇到这个问题,必须要总结一下!!

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <style type="text/css">
 8         li{
 9              100px;
10             height: 50px;
11             background-color: red;
12             margin-bottom: 10px;
13         }
14     </style>
15     <body>
16         <ul id="ulList">
17             <li></li>
18             <li></li>
19             <li></li>
20             <li></li>
21         </ul>
22         <script>
23             var lis = document.getElementById("ulList").getElementsByTagName("li");
24             for(var i=0;i<lis.length;i++){
25               lis[i].onclick = function(){
              console.log(i);  
            }30 } 31 </script> 32 </body> 33 </html>

如果按照以上方法,无论点击哪一个li标签,i的值都会是4,并不能像我们所想的那样打印出0,1,2,3,原因是什么呢?

暂时也不太清楚,好像涉及闭包,因为也没学到,就参考别人回答总结一下。

for循环是一个外部闭包,依次绑定的点击事件是一个函数实例,也产生了一个闭包域,它引用了外部闭包的变量i,外部闭包域中i的最终值为4,点击事件触发时引用外部闭包变量i(此时i=4),所以输出的值全为4。

暂时先写两种自己能掌握的解决方法:

方法一:在for循环中点击事件外套一个自执行的匿名函数,将索引变量i保存到匿名函数的形参中

 1 <script>
 2             var lis = document.getElementById("ulList").getElementsByTagName("li");
 3             for(var i=0;i<lis.length;i++){
 4                 (function(arg){
 5                     lis[i].onclick = function(){
 6                         console.log(arg);
 7                     }
 8                 })(i);
 9             }
10 </script>

方法二:在for循环中,为每一个要点击的对象创建属性用来保存索引变量i

 1 <script>
 2             var lis = document.getElementById("ulList").getElementsByTagName("li");
 3             for(var i=0;i<lis.length;i++){
 4                 lis[i].i = i; //创建属性保存变量i
 5                 lis[i].onclick = function(){
 6                     console.log(this.i);
 7                     // console.log(lis[i].i);绝对不能这样写,要不然 Uncaught TypeError: Cannot read property 'i' of undefined
 8                 }
 9             }
10         </script>
原文地址:https://www.cnblogs.com/Ryan777/p/10405262.html