首页 > 代码库 > JavaScript 闭包初认识

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的值。

JavaScript 闭包初认识