• JavaScript 闭包初认识


    1.简单的例子

    首先从一个经典错误谈起,页面上有若干个div, 我们想给它们绑定一个onclick方法,于是有了下面的代码

     <ul id="divTest">
            <li>0</li> <li>1</li> <li>2</li> <li>3</li>
     </ul>
     <ul id="divTest2">
            <li>0</li> <li>1</li> <li>2</li> <li>3</li>
     </ul>

    初次实现:

     var div = document.getElementById("divTest");
        var spans = div.getElementsByTagName("li");
        for (var i = 0; i < spans.length; i++) {
            spans[i].onclick = function () {
                console.log(i);
            }
        } 

    结果:显示都是4,不是预期结果,想要的0,1,2,3,

    进行如下修改,得到预期效果

       var div2 = document.getElementById("divTest2");
        var spans2 = div2.getElementsByTagName("li");
        for (var i = 0; i < spans2.length; i++) {
            (function (num) {
                spans2[i].onclick = function () {
                    console.log(num);
                }
            })(i);
        } 

    2.究其缘由

    第一种方式,在页面加载后就会执行,当i的值为4的时候,判断条件不成立,for循环执行完毕,但是因为每个li的onclick方法这时候为内部函数,所以i被闭包引用,内存不能被销毁,i的值会一直保持4,直到程序改变它或者所有的onclick函数销毁(主动把函数赋为null或者页面卸载)时才会被回收。

    这样每次我们点击li的时候,onclick函数会查找i的值(作用域链是引用方式),一查等于4,然后就显示给我们了。

    而第二种方式是使用了一个立即执行的函数又创建了一层闭包,函数声明放在括号内就变成了表达式,后面再加上括号括号就是调用了,这时候把i当参数传入,函数立即执行,num保存每次i的值。

  • 相关阅读:
    滚~滚~滚动条(移动端 )
    JS数据模板分离(告别字符串拼接)-template
    五子棋大战(人机)
    数据结构——队列
    数据结构——栈
    mysql下的SELECT INTO语句
    海明校验码
    android 调出显示标题栏(title bar)
    Windows failed to start.界面下修复win8引导
    android 修改背景色(转)
  • 原文地址:https://www.cnblogs.com/sxhlf/p/6743253.html
Copyright © 2020-2023  润新知