今天遇到了利用循环给元素绑定事件的问题,相信大家应该都遇到过这个问题。
我的代码
var hint = ["必填,长度为4-18个字符", "", "再次输入相同密码", "格式: example@github.com", ""];
var inputIDs = ["ip-name", "ip-pwd", "ip-pwd-cfm", "ip-email", "ip-phone"];
for (var i = 0; i<hint.length; i++) {
document.getElementById(inputIDs[i]).addEventListener("focus", function (e) {
var tar = e.target.parentElement.getElementsByClassName("alert")[0];
tar.innerHTML = hint[i];
});
}
下面这段代码用闭包来解决的,但是我没看懂,为什么这样调用不会调用到循环结束时i的值了呢?
没有理解这里闭包的用法,有哪位可以解释一下吗?
for (var i = 0; i < 5; i++) {
var a = function(v){
return function(){
console.log(v)
}
}
document.body.addEventListener('click',a(i))
}
如果你不使用闭包,你引用的i就是全局作用域(看你的代码没有在一个函数里)里的i。
document.getElementById(inputIDs[i])
这里的i就是你绑定时候的i,但是当你调用绑定的事件的时候函数体里的i就不再是绑定时候的i而是循环执行完以后的i的值了,其实你能访问到循环执行完了的i的值也有点类似于闭包,函数执行完了,你还能访问还是里声明的变量。但是你使用了闭包就不一样了,
document.body.addEventListener('click',a(i))
这里把i以参数的形式传入a函数,这时候已经和循环里的i不一样了,他们指向了不同的地址只是值一样,如果这里你传入的参数是个对象类型,闭包函数里的参数就是你这个对象的引用的copy,你在循环下面修改了传入对象的属性,闭包函数里也会相应修改,但是修改对象的引用的话,闭包里则不会改变。