<button>测试一</button>
<button>测试二</button>
<button>测试三</button>
var btns = document.getElementsByTagName('button')
for(var i = 0; i < btns.length; i++) {
var btn = btns[i]
btn.onclick = function () {
alert(`第${i + 1}个`) // 点击哪个都弹出第四个。原因是:点击按钮执行 onclick 事件绑定函数的时候,for 循环已经结束了,i 是一个全局变量,此时已经变成了 3
}
}
解决方法:
实质就是作用域的问题。
- 使用 let 块作用域:
for(let i = 0; i < btns.length; i++) { var btn = btns[i] btn.onclick = function () { alert(`第${i + 1}个`) } }
- 使用闭包:把全局变量 i 以参数的形式传递到了立即执行函数中,在立即执行函数中定义 I 的形参 j,变量 j 就是在立即执行函数作用域中的局部变量了。相当于把每次的 i 都保存在一个局部变量中。
for (var i=0; i< btns.length; i++) { (function(j){ // 此处的形参 j 是局部变量 j var btn = btns[j] btn.onclick = function () { alert(`第${j + 1}个`) } })(i) // 此处的实参 i 是 var 声明的全局变量 i }
- 将每个 btn 所对应的 i 保存在 btn 上。
for(let i = 0; i < btns.length; i++) { var btn = btns[i] // 将每个 btn 所对应的 i 保存在 btn 上 btn.index = i btn.onclick = function () { alert(`第${this.index + 1}个`) } }