js闭包

关于JS的闭包,也没有一个很好的定义。我对它的理解 就是外部变量/函数可以访问内部函数的变量。

如下面代码输出

<script>
    var n = 0;
    function a1(){
        console.log(n) // 0
    }
    a1();
    function a2() {
        var b = 1;
    }
    console.log(b) //error:b is not defined
</script>

这是因为函数内部可以直接读取全局变量,而外部却是无法读取内部变量的。那么,怎么才能读取内部的变量呢,只要把作为一个返回

值就可以了。

    function a2() {
        var b = 1;
        return b
    }
    var b = a2();
    console.log(b) //1

也可以返回一个函数

    function a3(){
        var i = 0;
        function bbb(){
            console.log(i++)
        }
        return bbb
    }
    var fn = a3();
    fn()//0
    fn()//1

上面的代码fn再次执行时不再是0,因为a3函数执行完后理论上是回收内存,但是return返回bbb,这就导致了始终在内存中,不会在调用结束后被垃圾回收机制回收。

关于闭包的用途,它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

如下面的代码

    <ul id="ul">
        <li>1111</li>
        <li>1111</li>
        <li>1111</li>
        <li>1111</li>
    </ul>
    <script>
        var oUl = document.getElementById("ul");
        var oLi = oUl.getElementsByTagName('li');
        for (var index = 0; index < oLi.length; index++) {
            oLi[index].onclick = function () {
                console.log(index)//4
            }
        }
    </script>

  我们想要的结果是点击当前 就是显示当前index,但是每次点击都是输出4,为什么?因为for循环,当等于4时不满足条件,没有执行。而这些都是瞬间执行完的,所以每次都是输出4;那么 这时可以用闭包就可以解决了,如下面代码。

    <ul id="ul">
        <li>1111</li>
        <li>1111</li>
        <li>1111</li>
        <li>1111</li>
    </ul>
    <script>
        var oUl = document.getElementById("ul");
        var oLi = oUl.getElementsByTagName('li');
        for (var index = 0; index < oLi.length; index++) {
            oLi[index].onclick = function (i) {
                return function () {
                    console.log(i)

                }
            }(index)
        }
    </script>

使用闭包有以下几大好处:

 1:希望一个变量长期驻扎在内存中。

    2:避免全局变量的污染。

 3:私有成员的存在。

当然了,有好处也是 有坏处。闭包使用不当会导致内存泄露问题,特别是IE浏览器下    

 

posted @ 2019-02-01 00:37  H柷H  阅读(280)  评论(0编辑  收藏  举报