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

在这里插入图片描述

一:执行上下文

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

执行上下文的类型

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

示例

image-20230907172008540

二:生命周期

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

2.1 创建阶段

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

具体包含三件事

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

执行上下文对象

伪代码

    //执行上下文对象
    const executionContext = {
      //确定this值
      ThisBindings =  { .....},
      //创建词法环境
      LexicalEnvironment =  { ....},
      //创建变量环境
      VariableEnvironment =  { ....},
    }
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>  
  }  
}
  • 在创建执行上下文的时候,会对不同的执行上下文对象的词法环境类型进行记录
    • 全局执行上下文的词法环境就是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)

执行上下文对象

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>  
  }  
}

全局执行上下文对象

  • 词法环境:收集变量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');

img

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值