js闭包-在你身边却不知

今天组里小伙很纳闷的问了我js绑事件带出的一个小问题,随便聊聊闭包那点事,背景如下:

当点击Button的时候给li绑定事件,事件的大概内容是获取li位置的index再做点事,据他描述代码看上去也没错,就是index一直是最后一个值

UI代码:

<button id="btnAttach"></button>

<ul id="ulTarget">
    <li>我是第一个</li>
    <li>我是第二个</li>
    <li>我是第三个</li>
    <li>我是第四个</li>
</ul>

 

js代码:

$("#btnAttack").bind("click",
    function(){
        var a = $("#J_memberslide").find("li");
        for(var i=0;a && i<a.length;i++){
        $(a[i]).bind("click",
        function(){
            alert(i);
            });
        }
    a=null; });

 
当然demo代码是精简过的示意代码,大概意思是点击按钮后,让ul下的li绑定click事件,click事件的内容是输出当前li的positioin的index值。

代码结果:点击任意一个li,输出都是3

 

代码分析

按钮事件内,通过循环的方式给每个li对象绑定了事件,事件的主体为一匿名函数,这里的匿名函数就成了一个闭包,在匿名函数内部引用了外部的变量i, 当函数执行时输出i的值

 

问题
为什么当点击触发匿名事件时,i的值一直是3

 

答案

当按钮事件绑定时,闭包引用的外部变量i的值并未被闭包访问,仅引用了变量i,即当循环绑定结束后i的值为3,而不绑定时取到i的值并保存,这是关键。

当li被点击时匿名函数才去访问变量i的值,即3,所以所有li点击时都输出的3

 

总结

闭包是JS经典特色之一,当它在你身边不必惊慌,也不要忽略

posted on 2016-12-07 17:12  晴天的故事  阅读(199)  评论(0编辑  收藏  举报