← 返回目录

第 4 卷

第 4 / 19 卷日期:

只有一个(浏览器中挂载在 window 对象,Node.js中挂载在 global 对象)。它的作用是初始化全局变量、全局函数,以及设置 this 指向全局对象。

  1. 函数执行上下文(Function Execution Context,FEC):每当调用一个函数时,JavaScript引擎

会为该函数创建一个新的函数执行上下文,函数执行完毕后,该上下文会被销毁(除非被闭包引用)。每个函数可以多次调用,每次调用都会创建一个独立的函数执行上下文。

  1. Eval执行上下文:使用 eval() 函数执行代码时创建的执行上下文,由于 eval() 存在安全风险

和性能问题,实际开发中很少使用,通常不推荐。

(3)执行上下文的生命周期

执行上下文的生命周期分为两个阶段,与JS代码执行的两个阶段对应:

  1. 创建阶段:函数调用后、代码执行前,引擎会完成以下三件事:
  • 确定 this 的指向( this 绑定);

◦ 创建变量对象(Variable Object,VO)/ 活动对象(Activation Object,AO):初始化变量、

函数声明、参数等;

  • 构建作用域链(Scope Chain)。
  1. 执行阶段:逐行执行代码,完成以下操作:
  • 变量赋值、函数调用、表达式计算;
  • 从变量对象/活动对象中读取或写入变量值;
  • 处理异常等。

(4)执行上下文对JavaScript代码执行的影响

  1. 管理代码执行顺序:JavaScript引擎通过**执行上下文栈(Execution Context Stack,ECS,也叫

调用栈)**来管理执行上下文。全局执行上下文先入栈,每当调用函数时,新的函数执行上下文入栈并成为“当前执行上下文”;函数执行完毕后,其执行上下文出栈,控制权交还给上一个执行上

下文,确保代码按顺序执行。

Code block

1function a() { 2b();

3console.log("a函数执行");

4} 5function b() {

6console.log("b函数执行");

12// 3.调用b(),b函数执行上下文入栈(FEC-b),成为当前上下文
13// 4. b()执行完毕,FEC-b出栈
14// 5. a()执行完毕,FEC-a出栈
15// 6.程序结束,GEC出栈
  1. 决定变量的可访问性:执行上下文的作用域链决定了变量的查找路径,只有在当前上下文或上层上

下文的变量对象中存在的变量,才能被访问,否则抛出异常。

  1. 确定 this 的指向:在执行上下文创建阶段就完成了 this 绑定, this 的指向在创建阶段就已

确定(箭头函数除外,箭头函数的 this 继承自上层执行上下文),决定了函数执行时的上下文对象。

  1. 管理变量的生命周期:全局执行上下文的变量生命周期伴随程序运行,函数执行上下文的变量(未

被闭包引用)在函数执行完毕后随上下文销毁,被闭包引用的变量则会被持久化。

  1. JavaScript代码的执行过程是怎么样的?

JavaScript代码的执行是一个有序、分阶段、依赖执行上下文和调用栈的过程,核心分为全局执行和函数执行两部分,具体步骤如下:

(1)全局代码执行过程

  1. 初始化全局执行上下文(GEC)- 创建阶段
  • 绑定全局 this 指向(浏览器: window;Node.js: global);

◦ 创建全局变量对象(VO),初始化全局变量( var 声明的变量设为 undefined)、全局函

数声明(完整函数体)、内置对象;

  • 构建全局作用域链(仅包含全局变量对象)。
  1. 执行全局代码 - 执行阶段
  • 逐行执行全局代码,完成全局变量的赋值操作;
  • 若遇到函数调用,则触发函数执行上下文的创建和入栈;

◦ 若遇到 let / const 声明的变量(未被提升到全局顶部),则在其声明位置完成初始化(未

赋值前处于“暂时性死区”)。

  1. 全局代码执行完毕

◦ 全局执行上下文仍保留在调用栈中(直到页面关闭/进程退出),等待事件触发(如定时器、

DOM事件)再次执行代码。

◦ 绑定函数 this 指向(根据调用方式确定,如普通调用指向全局,对象方法调用指向对象

等);

◦ 创建活动对象(AO),初始化函数参数(形参赋值为实参,未传递的形参设为

undefined)、 arguments 对象、函数内部变量( var 声明设为 undefined)、函数内部函数声明;

  • 构建函数作用域链(当前函数AO + 外层作用域的变量对象/AO + ... + 全局VO)。
  1. 执行函数代码 - 执行阶段
  • 逐行执行函数内部代码,完成变量赋值、表达式计算;
  • 若遇到嵌套函数调用,则重复上述函数执行步骤,新的函数执行上下文入栈;
  • 变量查找时,按作用域链从当前AO向上查找。
  1. 函数代码执行完毕
  • 若函数有返回值,则将返回值传递给调用者;
  • 该函数执行上下文出栈并销毁(其AO也随之销毁,除非被闭包引用);
  • 控制权交还给上一个执行上下文。

(3)核心总结

JavaScript代码执行的核心逻辑是:先创建执行上下文(编译阶段),再执行代码(执行阶段);全局上下文先入栈,函数调用时函数上下文入栈,执行完毕出栈;变量查找依赖作用域链, this 指向

在上下文创建阶段确定。

12. JavaScript在执行的过程中会产生AO、GO、VO、LE、VE、ER都是什

么对象?

这些对象都是JavaScript引擎在执行代码时创建的内部对象,用于存储执行上下文的相关信息,具体说明如下:

缩写全称中文名称核心说明
VOVariable Object变量对象1. 是执行上下文的

象,用于存储当前量、函数声明、参

<br>2. 仅在创建阶执行阶段会转换为

(AO)(函数上下

全站分卷索引 · 19 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷