美文网首页
JS进阶系列之闭包(2)

JS进阶系列之闭包(2)

作者: McRay | 来源:发表于2017-06-15 16:05 被阅读0次

    刚刚总结完作用域链,我觉得很有必要马上对闭包总结一下,因为,之前也写过自己对闭包的理解,那时候只知道,闭包就是可以访问别的函数变量的函数,就是在函数里面的函数就叫做闭包,可是并没有深入探究,为什么,可以访问别的函数变量呢?直到,学习了JS的作用域链之后,就恍然大悟。

    首先,来回顾一下,什么是作用域链吧。

    作用域链就是由当前执行环境与上层环境的一系列变量对象组成,保证了当前执行环境对符合访问权限的变量和函数的有序访问。

    那么什么是闭包呢?

    闭包

    关于闭包的定义,我在之前的文章里面已经讲过了,就是能够读取其它函数内部变量的函数,那么为什么闭包可以读取其它函数内部的变量呢?这里面就涉及到了作用域链

    demo01
    var fn = null;
    function foo(){
          var a = 2;
          function innerFoo(){
                   console.log(a);
          }
          fn = innerFoo();
    }
    function Bar(){
         fn();
    }
    foo();
    Bar();
    

    在这个例子里面,正常来说,按照作用域链的规则,在foo()函数的内部innerFoo()函数可以访问到,父级foo()的属性和方法,还有全局作用域下的属性和方法。这是因为,在innerFoo()的作用域链里面包含了fooECglobalEC的变量对象,所以有权限访问。
    但是,之前讲过的垃圾回收机制提到,如果foo()方法执行完毕,应该释放内存,然后让垃圾回收机制回收,可是,为什么在Bar()里面依然能访问到fn()方法呢?

    image.png

    从上图可以看出,因为fn = innerFoo();这句语句,使得全局作用域下的变量fn保存了innerFoo()方法的引用,并且innerFoo()方法是依赖于foo()方法的,所以导致,foo()方法里面的局部变量都保存在了内存里面,没有被回收,这也是使用闭包不当的一个弊端,会导致内存泄漏
    当执行Bar()方法的时候,Bar()的作用域链中包含了全局作用域下的变量对象,所以可以访问到foo()方法下的innerFoo(),这就是闭包的一个底层原理。

    相关文章

      网友评论

          本文标题:JS进阶系列之闭包(2)

          本文链接:https://www.haomeiwen.com/subject/gifuqxtx.html