循环遍历加监听的问题

本文详细分析了在JavaScript中使用`var`声明变量导致的循环遍历事件监听问题,指出由于异步执行,点击按钮时获取的`i`值始终为循环结束后的值。并提出了三种解决方案:1) 为每个按钮添加独立的`index`属性;2) 使用立即执行函数创建局部作用域;3) 利用`let`声明块级作用域。这三种方法都能确保点击每个按钮时正确显示对应的`i`值。
摘要由CSDN通过智能技术生成

1. 用var失败的原因

var btns = document.getElementsByTagName('button');
    for(var i = 0;i<btns.length;i++){
            btns[i].onclick = function () {
                alert(i);
            }
    }

点击监听事件是异步执行的,当点击按钮执行相应函数之前,同步任务(循环)已经执行结束,此时在全局作用域下的 i 已经为固定值。执行alert(i)时,沿着作用域链找到全局作用域下的 i ,导致点击每个按钮得到的结果相同。

2.  解决方法

2.1 添加属性

for(var i = 0;i<btns.length;i++){
            btns[i].index = i;
            btns[i].onclick = function () {
                alert(this.index);
            }
    }

原理:给每一个按钮绑定一个单独的属性,之后在执行点击监听的异步任务时,通过自己的属性来访问该值,不去访问全局作用域下的 i

2.2 立即执行函数

var btns = document.getElementsByTagName('button');
    for(var i = 0;i<btns.length;i++){
        (function (i) {
            btns[i].onclick = function () {
                alert(i);
            }
        })(i)
    }

原理:将每次执行for循环的 i 当作实参传入函数,在外部function函数中的 i 是局部变量,所以每次添加监听的 i 是不同的。由于闭包和作用域链,i 会一直存在,在执行点击的异步任务时可以访问到每个作用域下的 i

2.3 用let替换var

 var btns = document.getElementsByTagName('button');
    for(let i = 0;i<btns.length;i++){
            btns[i].onclick = function () {
                alert(i);
            }
    }

原理:let发挥效果在块级作用域,每个for循环下的代码都在相互独立的块级作用域下,在执行点击监听函数时,内部function的 i 顺着作用域链不会找到全局作用域去,而是在块级作用域找到每个独立的 i

参考:循环遍历加监听的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>