理解执行上下文

什么是执行上下文

执行上下文就是当前代码的执行环境,包含三种类型

  • 全局执行上下文:创建一个全局的window对象(浏览器的情况下),并且设置this的值等于这个全局对象。
  • 函数执行上下文:每当一个函数被调用时,都会为该函数创建一个新的上下文。每个函数都有它自己的执行上下文,不过是在函数被调用时创建的。
  • Eval 函数执行上下文

执行上下文生命周期

可以分为三个阶段

创建阶段

在这个阶段中,执行上下文会分别创建变量对象,建立作用域链,以及确定this的指向。

  1. 创建变量对象

    细节:当遇到函数和变量同名且都会被提升的情况,函数声明优先级比较高,因此变量声明会被函数声明所覆盖,但是可以重新赋值。

    function声明的优先级比var声明高,也就意味着当两个同名变量同时被function和var声明时,function声明会覆盖var声明

    1. 初始化函数的所有形参

      • 由名称和对应值组成的一个变量对象的属性被创建
      • 没有实参,属性值设为undefined
    2. 初始化函数声明

      • 由名称和对应值(function-object)组成一个变量对象的属性被创建
      • 如果变量对象已经存在相同名称的属性,则完全替换这个属性
    3. 初始变量声明

      • 由名称和对应值(undefined)组成一个变量对象的属性被创建

      • 如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性

  2. 建立作用域

    1. 上下文中的代码在执行的时候,会创建变量对象的一个作用域链。这个作用域链决定了各级上下文中的代码在访问变量和函数时的顺序。内部上下文可以通过作用域链访问外部上下文中的一切,但外部上下文无法访问内部上下文中的任何东西。
  3. 确定this指向

    • this的值是在执行的时候才能确认,定义的时候不能确认(箭头函数例外,箭头函数并不绑定this对象,this引用会从上层作用域中找到对应的this)

执行阶段

一步步执行,完成对所有变量的分配,最后执行代码

回收阶段

什么是执行上下文栈

用于存储在代码执行期间创建的所有执行上下文,当 JavaScript 引擎首次读取你的脚本时,它会创建一个全局执行上下文并将其推入当前的执行栈。

  • 每当发生一个函数调用,引擎都会为该函数创建一个新的执行上下文并将其推到当前执行栈的顶端,引擎会运行执行上下文在执行栈顶端的函数
  • 当此函数运行完成后,其对应的执行上下文将会从执行栈中弹出,上下文控制权将移到当前执行栈的下一个执行上下文。