刚刚总结完作用域链,我觉得很有必要马上对闭包总结一下,因为,之前也写过自己对闭包的理解,那时候只知道,闭包就是可以访问别的函数变量的函数,就是在函数里面的函数就叫做闭包,可是并没有深入探究,为什么,可以访问别的函数变量呢?直到,学习了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()方法呢?

JS进阶系列之闭包

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

相关文章:

  • 2021-08-23
  • 2021-07-29
  • 2021-07-10
  • 2021-09-26
  • 2022-12-23
  • 2021-11-28
  • 2021-09-20
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-09-21
  • 2022-12-23
  • 2021-05-31
  • 2022-02-17
  • 2021-12-13
  • 2022-01-06
相关资源
相似解决方案