• JS中执行上下文和执行栈是什么?


    在这里插入图片描述

    一:执行上下文

    执行上下文是一种对js执行代码的环境的一种抽象,只要js在执行中,那它一定是运行在执行上下文中

    执行上下文的类型

    • 全局执行上下文:全局执行上下文是在程序启动时创建的,它包含全局范围定义的变量和函数。在浏览器中,通常是在页面加载时候创建的,它是在页面整个生命周期中都存在的。
    • 函数执行上下文:存在无数个函数执行上下文,但是只有函数被调用时候才会创建函数执行上下文。函数执行上下文包含函数作用域范围内的变量,函数参数,函数和作用域链。
    • eval执行上下文: 指的是运行在 eval 函数中的代码,很少用而且不建议使用

    示例

    image-20230907172008540

    二:生命周期

    执行上下文的生命周期为:创建阶段 —> 执行阶段 —> 销毁阶段

    2.1 创建阶段

    • 创建阶段:在代码执行之前,会进行对执行上下文的创建
      • 全局执行上下文的创建:在整个程序启动时候,会创建全局执行上下文,其中包含全局函数,全局变量的创建、
      • 函数执行上下文的创建:在函数被调用时,在函数执行前会创建函数执行上下文,其中会构建局部变量,局部函数和作用域链

    具体包含三件事

    • ThisBinding:this的绑定
    • LexicalEnvironment(词法环境):创建词法环境
    • VariableEnvironment(变量环境):创建变量环境

    执行上下文对象

    伪代码

        //执行上下文对象
        const executionContext = {
          //确定this值
          ThisBindings =  { .....},
          //创建词法环境
          LexicalEnvironment =  { ....},
          //创建变量环境
          VariableEnvironment =  { ....},
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    ThisBinding

    this 的值是在执行时(运行时)确定的,而不是在执行上下文创建时确定的。这意味着 this 的绑定是动态的,取决于代码的实际执行情况。

    词法环境

    词法环境(Lexical Environment)是 JavaScript 中的一个重要概念,用于管理变量和函数的词法作用域

    环境记录(Environment Record):环境记录是一个存储变量和函数声明的地方。它可以看作是一个字典或映射,将标识符(如变量名、函数名)映射到对应的值。环境记录有以下两种主要类型:

    • Declarative Environment Record(声明式环境记录): 用于存储变量声明、函数声明等。这种记录可以包含诸如函数的参数、局部变量、函数声明等。
    • Object Environment Record(对象环境记录): 用于与具体的对象相关联,典型的例子是与全局对象或某个特定对象的属性相关联。在这种记录中,标识符会映射到对象的属性上。
    GlobalExectionContext = {  // 全局执行上下文
      LexicalEnvironment: {       // 词法环境
        EnvironmentRecord: {     // 环境记录
          Type: "Object",           // 全局环境
          // 标识符绑定在这里 
          outer: <null>           // 对外部环境的引用
      }  
    }
    
    FunctionExectionContext = { // 函数执行上下文
      LexicalEnvironment: {     // 词法环境
        EnvironmentRecord: {    // 环境记录
          Type: "Declarative",      // 函数环境
          // 标识符绑定在这里      // 对外部环境的引用
          outer: <Global or outer function environment reference>  
      }  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 在创建执行上下文的时候,会对不同的执行上下文对象的词法环境类型进行记录
      • 全局执行上下文的词法环境就是Object Environment Record,对象环境记录
      • 函数执行上下文的词法环境就是Declarative Environment Record,声明式环境记录
    变量环境

    变量环境实际上是词法环境的一个子集

    • 词法环境用于收集存储函数的声明和变量(letconst)的绑定
    • 变量环境用于存储变量(var)的绑定

    伪代码

        let a = 10
        const b = 100
        var c = 20
    
        function sum (number1, numebr2)
        {
          var res = 0
          return res + number1 + number2
        }
    	c = sum(20, 30)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    执行上下文对象

    GlobalExectionContext = {
    
      ThisBinding: <Global Object>,
    
      LexicalEnvironment: {  // 词法环境
        EnvironmentRecord: {  
          Type: "Object",  
          // 标识符绑定在这里  
          a: < uninitialized >,  
          b: < uninitialized >,  
          sum: < func >  
        }  
        outer: <null>  
      },
    
      VariableEnvironment: {  // 变量环境
        EnvironmentRecord: {  
          Type: "Object",  
          // 标识符绑定在这里  
          c: undefined,  
        }  
        outer: <null>  
      }  
    }
    
    FunctionExectionContext = {  
       
      ThisBinding: <Global Object>,
    
        //词法环境
      LexicalEnvironment: {  
        EnvironmentRecord: {  
          Type: "Declarative",  
          // 标识符绑定在这里  
          Arguments: {0: 20, 1: 30, length: 2},  
        },  
        outer: <GlobalLexicalEnvironment>  
      },
          
    	//变量环境
      VariableEnvironment: {  
        EnvironmentRecord: {  
          Type: "Declarative",  
          // 标识符绑定在这里  
          res: undefined  
        },  
        outer: <GlobalLexicalEnvironment>  
      }  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    全局执行上下文对象

    • 词法环境:收集变量let和const的绑定和函数提升
      • 由于let和const定义的a和b变量,不会出现变量提升,所以类型为uninitialized(未初始化状态)
      • sum出现函数提升
      • outer:由于是全局执行上下文,不会再有外部环境的引用,所以类型为Null
    • 变量环境:收集var定义的变量的绑定,由于var定义的变量会出现变量提升,会被初始化为undefined

    函数执行上下文对象

    • 词法环境:也收集函数参数
    • 变量类型:res变量提升

    2.2 执行阶段

    • 执行阶段:在创建完成之后,会进入执行阶段
      • 代码逐行进行执行,条件判断,语句赋值等都会进行执行
      • 如果遇到函数调用,则会创建函数执行上下文,并且将该函数的执行上下文压入到执行栈

    2.3 回收阶段

    • 当代码块执行完毕或函数执行完毕时,执行上下文进入执行结束和销毁阶段。
    • 在这个阶段,局部变量通常会被销毁,内存资源得到释放。

    三:执行栈

    let a = 'Hello World!';
    function first() {
      console.log('Inside first function');
      second();
      console.log('Again inside first function');
    }
    function second() {
      console.log('Inside second function');
    }
    first();
    console.log('Inside Global Execution Context');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    img

    执行上下文的创建和销毁是一个动态的过程,由 JavaScript 引擎负责管理。执行上下文的栈结构(调用栈)用于跟踪代码的执行顺序,并确保上下文按照正确的顺序进入和离开。这种生命周期管理有助于确保变量的作用域、函数的调用顺序和内存资源的释放都得以正确执行。

  • 相关阅读:
    Mysql的日志系统 redo log 和binlog
    云目录助力微软 AD 的远程办公场景
    linux添加普通用户并且只能访问指定目录
    java中的异常,以及出现异常后的处理【try,catch,finally】
    【刷爆LeetCode】七月算法集训(30)拓扑排序
    号码吉凶查询易语言代码
    Java零基础入门-位运算符
    《006.Springboot+vue之旅游信息推荐系统》【有文档】
    C#:实现SHA1加密算法(附完整源码)
    C++Prime Plus(7)
  • 原文地址:https://blog.csdn.net/Czc1357618897/article/details/132744935