我的编程空间,编程开发者的网络收藏夹
学习永远不晚

深入学习JavaScript执行上下文

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

深入学习JavaScript执行上下文

前言

我们先不看这个标题,来看下面这段代码是怎么运行的:

var num1=1
var num1=2
var result=num1+num2
console.log(result)

我相信,小伙伴都知道打印的是3把,这也太简单了,但是我们思考下,这段代码执行时,到底进行了怎样的操作,这里我们要引进一个概念:初始化全局对象和执行上下文

初始化全局对象(GO)

JS引擎在解析代码的时候,会在堆内存中创建一个全局对象叫:Gobal Object(GO)

  • 该对象所有的作用域都可以访问
  • 里面会包含Date Array String Number setTimeout setInterval 等等
  • 还有一个windows属性指向本身

执行上下文

代码运行时:js引擎(这里考虑V8引擎)会创建执行上下文栈(Execution context stack)简称ECS,它就是执行代码的调用栈

执行上下文分为:

  • 全局执行上下文( GEC )
  • 函数执行上下文( FEC )

这里我们先分析下全局执行上下文,因为我们开头那段代码是全局代码

全局执行上下文

在执行全局代码的时候,会创建全局执行上下文( GEC ),GEC会被放入ECS中去执行 GEC被放入ECS

包含两部分:

  • 第一部分:在代码执行前,也就是V8引擎将parser转成AST的过程中 ( 这里会涉及到V8引擎在解析js代码的过程,会开篇专题讲这个),会将全局定义的变量放入GO中,但是并不会赋值,因为是解析阶段 (pass:这个过程也被叫做变量的作用域提升
  • 第二部分:执行代码,并为GO里面的变量赋值,或者执行其他函数 流程图如下:图中执行前是上面描述的第一部分,开始执行代码是第二部分

Java Script遇到函数代码如何执行?

当js引擎遇到函数执行时,会创建一个 函数执行上下文( Functional Execution Contex ) 简称FEC,并压入到执行上下文栈ECS

FEC中包含三部分内容:

  • 第一部分:VO(variable object ) 对象,其实也是AO( Activation Object )
  • 第二部分:作用域链(scope chain):由自己的VO+父级的VO,查找时会一层一层去查找
  • 第三部分:this绑定( 这里不做详细描述,后续会出专题 )

作用域是解析编译的时候就决定了,并不是执行调用的时候来我们看一段代码,一起看一下函数的执行过程,一起来思考下这段代码的运行结果

var message = "Global"
function foo() {
  console.log(message)
}
function bar() {
  var message = "Bar"
  foo()
}
bar()

画个图分析一下吧

首先初始化全局对象GO,里面有Array、date、setTime等等,还有自己定义的 message对象初始值为undefined,foo和bar函数对象

开始执行代码前,会创建一个执行上下文栈ESC,开始执行全局代码,所以会创建一个全局执行上下文栈GEC,将GEC压入栈底,全局执行上下文包括两部分:
第一部分代码执行前的VO对象(这里的VO指向的是GO)
第二部分是开始执行代码,执行第一行时 var message="Global",GO对象里的message就被改为Global 

执行完第一行后,开始执行第9行代码 bar(),这里是函数的调用执行,js引擎会创建一个函数执行上下文FEC,压入栈中,FEC包含三部分:

第一部分:VO对象,这里指向bar自己的AO对象(包括形参和函数中定义的变量)
第二部分:作用域链scope chain,自己的VO对象+parent VO对象

第三部分:this绑定,这里是指向windows(这个后续会开专题讲)
开始执行bar函数里面的代码,var message="Bar",会将bar的AO对象的message变量值从undefined改为"Bar",接下来在执行foo()函数,注意:此时bar函数还没弹出栈,因为foo函数还在执行

访问一个变量的时候,会沿着作用域链一层一层往上找,最后没有找到则会报错

执行到bar函数的最后一行代码是foo(),此时又是一个函数的调用执行,又会创建一个foo的函数执行上下文,也包含上述的三部分:VO对象(指向foo的AO对象) 作用域链 和this绑定
开始执行foo函数代码console.log(message),当打印message的时候,会沿着作用域链一层层找foo的作用域链是自己的AO+父级的VO(也就是GO对象),自己的AO对象为空,所以找到GO里面的message变量,最终打印"Global" 

执行完后,函数执行上下文执行完之后,就会弹出栈,foo的FEC先弹出栈,然后bar的FEC弹出栈,他们自个的AO对象最终也被释放

环境变量和记录

我们上述所说的VO是基于早期的ECMAS规范,官网是这样说的:

 这里借助coderwhy的翻译:每个执行上下文都关联一个变量对象(Vriable Object),在源代码中变量和函数的声明会被作为属性加入到变量对象中,对于函数来说,参数也会被加入到VO中但是ECMA5以后的版本,官网做了一些词汇用语的修改 

每个执行上下文都会关联一个变量环境(variable Environment),在执行代码中变量和函数的声明会被当做环境记录(Environment Record)加入到变量环境中。
对于函数代码,形参也会被当做环境记录加入到变量环境中

总结:

  • 在访问一个变量时,会沿着作用域链一层层往上找,最终没找到,会报错:未定义
  • 作用域以及父级作用域是代码在编译阶段就已经确定了,和调用位置没关系

汇总一些名词解释,我们来解释一下:

名词解释
ECS执行上下文栈 (Execution Context Stack),也可称为调用栈
GEC全局执行上下文(Global Execution Context),在执行全局代码前创建
FEC函数执行上下文(Functional Execution Context),在执行函数前创建
VOVariable Object,早期ECMA规范中的变量环境,对应Object
VEVariable Environment,最新ECMA规范中的变量环境,对应环境记录
GO全局对象(Global Object),解析全局代码时创建,GEC中关联的VO就是GO
AO活动对象(Activation Object),VO被激活就变成了AO,VO和AO本质上是一个东西,它们其实都是同一个对象,只是处于执行环境的不同生命周期

到此这篇关于深入学习JavaScript执行上下文的文章就介绍到这了,更多相关JS执行上下文内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

深入学习JavaScript执行上下文

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

深入学习JavaScript执行上下文

这篇文章主要介绍了深入学习JavaScript执行上下文,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下,希望对你的学习有所帮助
2022-11-13

深入理解函数执行上下文this

这篇文章主要为大家介绍了深入理解函数执行上下文this示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

javascript执行上下文详解

执行上下文可以说是js代码执行的一个环境,存放了代码执行所需的变量,变量查找的作用域链规则以及this指向等。同时,它也是js很底层的东西,很多的问题如变量提升、作用域链和闭包等都可以在执行上下文中找到答案,所以这也是我们学习执行上下文的原因
2023-05-18

JavaScript怎么执行上下文

这篇文章主要介绍了JavaScript怎么执行上下文,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、怎么描述执行上下文1.1 本节知识导图:1.2 如果描述执行上下文当函数
2023-06-14

JavaScript执行上下文和执行栈是什么

本篇内容介绍了“JavaScript执行上下文和执行栈是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是执行上下文?简而言之,执行上
2023-06-27

一文聊聊Javascript中的执行上下文

本篇文章带大家聊聊Javascript中的执行上下文,分享一个思考题,通过对思考题的分析,想必会对执行上下文有更加深入的理解。
2023-05-14

Javascript中的执行上下文如何创建

这篇文章主要介绍“Javascript中的执行上下文如何创建”,在日常操作中,相信很多人在Javascript中的执行上下文如何创建问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Javascript中的执行上
2023-07-05

JavaScript执行上下文中的this怎么使用

这篇文章主要讲解了“JavaScript执行上下文中的this怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript执行上下文中的this怎么使用”吧!前言在对象内部的方
2023-07-05

JavaScript中执行上下文的原理是什么

这期内容当中小编将会给大家带来有关JavaScript中执行上下文的原理是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。执行上下文执行上下文是当前代码的执行环境。执行上下文主要是三种类型:全局执行上下
2023-06-15

JavaScript函数执行上下文的this怎么调用

今天小编给大家分享一下JavaScript函数执行上下文的this怎么调用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Ja
2023-07-04

JavaScript 执行上下文的视角详解this使用

这篇文章主要为以JavaScript 执行上下文的视角为大家讲清楚 this使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-02-27

一文带你掌握JavaScript中的执行上下文和作用域

作为一名前端工作人员,我们必须知道JavaScript内部是如何执行的。那对于执行上下文和作用域的理解至关重要,无论是工作还是面试都是无法跳跃的一步,本文就来带大家深入了解一下
2023-02-08

编程热搜

目录