for循环中var和let的不为人知的秘密

昨天考核同学js的时候问到了这个问题,结果自己忘了还有一些条件,结果当场翻车,。。。。后来试了几次,才发现问题所在。。想想就好笑,治学要严谨啊,马虎不得。
直接看代码

<script>
 for (let i = 0; i < 4; i++) {
        console.log(i);
    }
 //结果为 0 1 2 3    
    for (var i = 0; i < 4; i++) {
        console.log(i);
    }
    console.log(i);
//结果为0 1 2 3
</script>

然后我们尝试在html中加点代码
我们在ul中创建四个li,为方便观看,将ul的背景颜色设置为红色
在这里插入图片描述

<ul style="background-color: red;width: 100px">ul
          <li>li1</li>
          <li>li2</li>
          <li>li3</li>
          <li>li4</li>
      </ul>

然后我们再使用两个for循环打印每个li标签

var lis=document.querySelectorAll('li'); //获取所有li标签
    for (let i = 0; i < 4; i++) {   //let循环打印
        console.log(lis[i]);
    }
    for (var i = 0; i < 4; i++) {   //var循环打印
        console.log(lis[i]);
    }

在这里插入图片描述
通过控制台,我们可以看到两个循环都成功打印出每个li标签,确实没什么毛病,嗯。
然后我们在此基础上为两个循环遍历得到的li标签分别添加不同的效果,奇迹发生了,不要眨眼睛啊

// for 循环使用let 添加点击事件,改变每个li标签的颜色为蓝色
 var lis=document.querySelectorAll('li');
    for (let i = 0; i < 4; i++) {
        // console.log(lis[i]);
       lis[i].addEventListener('click',function (){
           lis[i].style.color='blue';
       })
    }

结果如我们所料
在这里插入图片描述
然后再使用for循环var

//for循环使用var为每个li添加绑定事件,改变颜色为绿色
for (var i = 0; i < 4; i++) {
        // console.log(lis[i]);
        lis[i].addEventListener('click',function (){
            // console.log(i);
            // console.log(this);
            lis[i].style.color='gerrrn';
        })
    }

结果是我们无论怎么点击就是触发不了我们的预期效果,之前我们明明使用for循环中的var选取到了每个li标签,为什么就是没效果呢,而且还报错。
在这里插入图片描述
原来这其中还牵涉到同步异步的思想
当执行上下文到for循环中,会把for循环放到同步执行栈中,执行for循环,然后把for循环中的内部点击事件放到异步方法里面。等到同步任务,也就是for循环执行完之后再执行里面的点击事件。
我们可以在点击事件后把i打印出来

 for (var i = 0; i < 4; i++) {
        // console.log(lis[i]);
        lis[i].addEventListener('click',function (){
            console.log(i);//4
            lis[i].style.color='orange';
        })
    }
    console.log(i)=4;

在这里插入图片描述
我们可以看到每次点击都会打印出i的值为4,数组lis的长度为4,数组最大索引为3,所以找不到lis[4]。
为什么i是4?因为for循环最后一次循环i=3又执行了一步i++的操作,所以为4.

为了防止出现这种难以预期的意外,我们可以把lis[i]改为this,因为this在这里指的是点击的对象。

```html
 for (var i = 0; i < 4; i++) {
        // console.log(lis[i]);
        lis[i].addEventListener('click',function (){
            console.log(i);//4
            console.log(this);
            this.style.color='orange';
            //lis[i].style.color='orange';
        })
    }
    console.log(i)=4;

在这里插入图片描述

关于同步异步的理解可以参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值