javascript - 为什么闭包可以解决js中循环绑定事件的问题?

查看:86
本文介绍了javascript - 为什么闭包可以解决js中循环绑定事件的问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

今天遇到了利用循环给元素绑定事件的问题,相信大家应该都遇到过这个问题。

我的代码

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,你在循环下面修改了传入对象的属性,闭包函数里也会相应修改,但是修改对象的引用的话,闭包里则不会改变。

这篇关于javascript - 为什么闭包可以解决js中循环绑定事件的问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆