前端百题斩【010】——通俗易懂的JavaScript执行上下文

本文详细解析了JavaScript的执行上下文,包括全局、函数和eval执行上下文的类型,以及它们的生命周期和执行过程。重点介绍了执行上下文的创建阶段和执行阶段,阐述了代码如何在调用栈中执行,并通过实例说明了调用栈的工作原理。此外,文章还总结了执行上下文的关键结论,如全局上下文的唯一性、函数执行上下文的动态创建等。
摘要由CSDN通过智能技术生成

写该系列文章的初衷是“让每位前端工程师掌握高频知识点,为工作助力”。这是前端百题斩的第10斩,希望朋友们关注公众号“执鸢者”,用知识武装自己的头脑。

JavaScript标准把一段代码(包括函数)执行所需的所有信息定义为“执行上下文”(可理解为当前代码的执行环境,同一个函数在不同的环境中执行,会因访问的数据不同产生不一样的结果),其是执行的基础设施。执行上下文包含的内容有很多,下面从类型、包含内容、生命周期、执行过程、结论来进行阐述。

img

10.1 类型

执行上下文主要分为三类:全局执行上下文、函数执行上下文、eval函数执行上下文。

  1. 全局执行上下文

当JavaScript执行全局代码的时候,会编译全局代码并创建全局执行上下文,而且在整个页面的生存周期内,全局执行上下文只有一份。

  1. 函数执行上下文

当调用一个函数的时候,函数体内的代码会被编译,并创建函数执行上下文,一般情况下,函数执行结束之后,创建的函数执行上下文会被销毁。

  1. eval执行上下文

当使用eval函数的时候,eval代码也会被编译,并创建执行上下文。

10.2 包含内容

执行上下文在不同的版本中定义不同,《重学前端》中对此进行了总结,目前主要有三个版本:

  1. 执行上下文在ES3中,包含三个部分。

  • scope:作用域,也常常被叫做作用域链。

  • variable object:变量对象,用于存储变量的对象。

  • this value:this值。

  1. 在ES5中,我们改进了命名方式,把执行上下文最初的三个部分改为下面这个样子。

  • lexical environment:词法环境,当获取变量时使用。(通过let、const、with()、try-catch创建的变量存在词法环境中)

  • variable environment:变量环境,当声明变量时使用。(通过var声明或function(){}声明的变量存在变量环境中)

  • this value:this值。

  1. 在ES2018中,执行上下文又变成了这个样子,this值被归入lexical environment,但是增加了不少内容。

  • lexical environment:词法环境,当获取变量或者this值时使用。

  • variable environment:变量环境,当声明变量时使用

  • code evaluation state:用于恢复代码执行位置。

  • Function:执行的任务是函数时使用,表示正在被执行的函数。

  • ScriptOrModule:执行的任务是脚本或者模块时使用,表示正在被执行的代码。

  • Realm:使用的基础库和内置对象实例。

  • Generator:仅生成器上下文有这个属性,表示当前生成器。

10.3 执行上下文生命周期

在执行上下文生命周期部分(将按照ES3阶段的内容进行介绍,因为自我感觉后续定义的名词内容虽然更全面,但背起来确实不是很容易),分为创建阶段和执行阶段两个阶段,每个阶段负责不同的事情。(注:,每一部分都是一个问题,详细解释看后续百题斩。)

  1. 创建阶段

创建阶段主要负责生成变量对象、建立作用域链以及确定this指向。

  1. 代码执行阶段

创建完成之后,就会开始执行代码,这个时候,会完成变量赋值,函数引用,以及执行其他代码。

10.4 代码执行过程

百题斩【008-009】介绍了代码和函数的执行过程,但是这个介绍只是从宏观方面进行介绍,并没有进行详细的介绍,下面将从调用栈这个角度详细阐述一下代码的执行过程。

  1. 创建 全局上下文 (global EC)。将其压入栈底;

  2. 全局执行上下文 (caller) 逐行 自上而下 执行。遇到函数时,函数执行上下文 (callee) 被push到执行栈顶层;

  3. 函数执行上下文被激活,成为 active EC, 开始执行函数中的代码,caller 被挂起;

  4. 函数执行完后,callee 被pop移除出执行栈,控制权交还全局上下文 (caller),继续执行;

下面将举一个例子来阐述该执行过程。

var a = 1;
function f1() {
    // ……
}

function f2() {
    f1();
    // ……
}

f2();

上述代码的调用栈如下所示:

image-20210516165656800.png
  1. 首先创建全局执行上下文,并将全局执行上下文压入栈底;其中变量a、函数f1和f2都将被保存在全局执行上下文的变量环境中;

  2. 全局执行上下文开始执行,变量a被赋值为1,当调用函数f2时,会创建对应的函数执行上下文并压入调用栈,在函数f2的执行上下文被创建好后,将进入代码执行阶段;

  3. 函数f2执行过程中会调用函数f1,创建对应的函数执行上下文并压入调用栈;f1进行执行阶段;

  4. f1函数返回时,该函数的执行上下文从栈顶弹出;

  5. 紧接着f2函数返回,f2函数对应的执行上下文也从栈顶弹出;

  6. 至此代码执行关闭,当完毕页面的时候全局执行上下文销毁。

10.5 结论

了解了执行上下文,需要记住一些结论性的东西

  1. 在调用栈中只有栈顶的上下文处于执行中,其他上下文需要等待;

  2. 全局上下文只有唯一的一个,它在浏览器关闭时出栈;

  3. 函数的执行上下文的个数没有限制;

  4. 每次某个函数被调用,就会有个新的执行上下文为其创建,并把该执行上下文压入调用栈,然后JavaScript引擎开支执行函数代码,即使是调用的自身函数,也是如此;

  5. 当前函数执行完毕后,JavaScript引擎会将该函数的执行上下文弹出栈;

  6. 当分配的调用栈空间被占满时,会引发“堆栈溢出”问题。

1.如果觉得这篇文章还不错,来个分享、点赞、在看三连吧,让更多的人也看到~

2.关注公众号执鸢者,领取学习资料,定期为你推送原创深度好文

3.扫描下方添加进群,里面大佬多多,一起向他们学习

1. 前端百题斩[001]——typeof和instanceof

2. 前端百题斩【002】——js中6种变量声明方式

3. 前端百题斩【003-004】——从基本类型、引用类型到包装对象

4. 前端百题斩【005】—— js中9种遍历对象的方法

5. 前端百题斩【006】——js中三类字符串转数字的方式

6. 前端百题斩【007】——js中必须知道的四种数据类型判断方法

7. 前端百题斩【008-009】——从JavaScript的代码执行过程到函数执行过程

8. (2.6w字)网络知识点灵魂拷问(上)——前端面试必问

9. (2.6w字)网络知识点灵魂拷问(下)——前端面试必问

10. 理论与API相结合理解Node中的网络通信

11. 硬核知识点——浏览器中的三类五种请求

12. 理论与实践相结合彻底理解CORS

13. 三步法解析Express源码

14. 一篇搞定前端高频手撕算法题(36道)

15. 十七张图玩转Node进程——榨干它

16. 理论与API相结合理解Node中的网络通信

17. 一文彻底搞懂前端监控

18. 前端的葵花宝典——架构

19. canvas从入门到猪头

20. 前端工程师的一大神器——puppeteer

21. 2021 年前端宝典【超三百篇】

22. 前端也要懂机器学习(上)

23. 前端也要懂机器学习(下)

24. 学架构助力前端起飞

25. 假如只剩下canvas标签

26. Vue源码思想在工作中的应用

27. 一文搞定Diff算法

28. 百度、小红书三面,均遇“赛马”问题

29. 十五张图带你彻底搞懂从URL到页面展示发生的故事

30. 一文搞懂Cookie、Storage、IndexedDB

31. 六张图带你从HTTP/0.9进化到HTTP3.0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值