Skip to the content.

从执行上下文与作用域来说闭包

  1. 执行上下文的作用
    • 执行上下文决定了一个变量或函数可以访问哪些数据以及他们的行为。
    • 每一个上下文都会有一个关联的变量对象,这个上下文中定义的所有变量和函数都存在于这个对象上,但是这个对象是无法通过代码直接访问到的。
    • 全局上下文是最外层的上下文—–在浏览器中通常就是window,所有通过var定义的全局变量和函数都会成为window对象的属性和方法
    • 使用let和const定义的顶级声明不会定义在全局上下文中,但是在作用域链解析上效果是一样的
    • 上下文在起所有代码都执行完毕后就会被销毁,上面定义的所有东西都被销毁了
  2. 上下文栈

    • 很好理解,就是说每一个函数开始被执行的时候,它的上下文就会被推到一个上下文栈上,代码执行完毕后,上下文栈就会弹出该函数的上下文
  3. 作用域链

    • 当一个上下文中的代码正在执行时,就会创建变量对象的一个作用域链
    • 作用域链决定了各级上下文中的代码能够访问到的变量和函数是哪些,还有查找各个变量和函数的顺序
    • 正在执行的上下文的变量对象始终位于作用域链的最前端
  4. 作用域链增强

    • try/catch 中的catch
    • with语句 —- with的参数会被添加到作用域链的最前端
  5. 变量声明

    • var — 变量被添加到最接近的上下文,var 声明会被拿到函数或全局作用域的顶部,位于作用域中所有代码之前。
    • let — 块级作用域
    • const —- 块级作用域,常量声明
  6. 标识符查找,从作用域链最前端开始,在全局作用域结束

  7. 垃圾回收

    1. 标记清理

      变量或函数进入上下文时就加上一个标记,垃圾回收开始的时候清楚所有上下文上变量和函数的标记,然后还有标记的变量或函数就是应该被清理的

    2. 引用计数

      每个值都记录它被引用的次数,垃圾回收程序每次释放饮用数为0的内存

      有问题:循环引用==>导致引用数永远都不会清零

    3. 内存管理

      1. 隐藏类和delete
      2. 内存泄漏
        1. 无关键字声明
        2. 定时器不清除
        3. 闭包引用
      3. 静态分配和对象池
  8. 闭包

    • 定义: 指的是哪些引用了另外函数作用中的变量的函数,通常是在嵌套函数中实现的
    • 原理: 内部函数的作用域链包含了被他嵌套函数的作用域
      • 调用一个函数时会为这个函数创建一个执行上下文和一个作用域链
    • 解除对函数的引用来释放内存!!!!这就是解决闭包导致内存泄漏的办法