共计 3855 个字符,预计需要花费 10 分钟才能阅读完成。
大伙儿好~,我是小鹿,公众号:「小鹿动画学编程」原创作者。
2021 第二期。
想必大伙儿看到本期的题目很有纳闷,为什么是 简而不单,单而不简的执行上下文 呢?我来先解释一下,对于 javaScript 上一些形象的概念,咱们能够把它讲的非常复杂,也能够把它讲的极其简略,更能够把它讲的既简单又简略。
嗯~ 最近从新回顾了这些形象的概念,发现有些概念之前并不能很好的死记硬背,所以把这些绝对形象难以了解的概念作为几期文章来写。
无妨关上在谷歌搜「执行上下文」关键词,几篇绝对排名靠前的优良文章回出现进去。
- [译] 了解 JavaScript 中的执行上下文和执行栈
- 深刻了解 JavaScript 执行上下文和执行栈
- JavaScript 深刻之执行上下文
看到这几篇文章,作者尽心尽力的去解释这些比拟形象的概念,文字很多,图绝对较少。我集体感觉要想更好的了解抽象概念,不得不借助可视化的图像缩小作者和读者之间的理解力和了解过错。所以,不必放心,这篇文章小鹿会通过退出更多的图片深入浅出的解释这些形象的概念。
本文章已在 Github blog 第二期 收录,欢送大伙儿~ Star,文章中若存在有余或者 issues,欢送在下方或 Github 留言!
本期目录
-
1、执行上下文
- 1.1 JavaScript 引擎
- 1.2 执行栈
- 1.3 执行上下文
-
2、执行上下文的分类
- 2.1 全局执行上下文
- 2.2 部分执行上下文
-
3、执行上下文两个阶段
- 3.1 创立阶段
- 3.2 执行阶段
- 4、小结
1、执行上下文
1.1 JavaScript 引擎
说到执行上下文,不得不先扯扯 JavaScript 引擎,JavaScript 引擎是什么?思考到这篇文章不专门写 JavaScript 引擎,能够本人谷歌一下。说白了,JavaScript
引擎就是用来「解释 」、「 编译 」和「 执行」JavaScript
代码的,毕竟开发人员写的 JS 代码只可能让开发者认得进去,交给计算机,因为计算机只辨认二进制,所以两头须要进行一系列的解释和转化才能看懂执行这些 JavaScript
代码。
1.2 执行栈 (Execution stack)
小鹿注:保障 JavaScript 代码的执行 "程序"。
JavaScript
引擎既然能够执行 JS
的代码,那么是依照什么程序执行的,又是怎么保障这些程序而不被所打乱的。先看一段简略的代码:
var foo2 = function () {console.log('foo2');
}
var foo1 = function () {console.log('foo1');
foo2()
console.log('foo3')
}
foo1(); // 输入:“foo1 foo2 foo3”
通过上述代码片段的执行,输入的程序为'foo1 foo2 foo3'
。
代码执行,foo1()
函数先执行,首先输入'foo1'
,遇到 foo2()
函数的执行命令,将执行权交给 foo2
,foo2
函数体执行,输入'foo2'
。foo2
执行结束后,将执行权交回 foo1
函数,最初输入'foo3'
。
咱们能够找出上述代码执行的法则,先执行的函数,会在最初退出,后执行的函数,先执行结束。这个执行程序不就是“栈”的 “先进后出”
`“后进先出” 的构造嘛。
JavaScript 引擎将其这种执行构造称为「** 执行栈 **」,用于保障
JavaScript` 代码的程序。
1.3 执行上下文(Exception Context)
小鹿注:将执行的代码 "模块化" —— 执行上下文的分类。
什么是执行上下文?尽管咱们在“执行上下文”词义上很难间接了解,然而它具体代表的是什么,是很容易了解的,上面我把“执行上下文”的抽象概念进行具体化。
上述咱们曾经解释了 JavaScript
引擎是应用执行栈来保障代码的执行程序的,然而执行过程中须要波及到一些变量的作用范畴界定(作用域)、闭包等简单状况,咱们须要 JavaScript 引擎引入一种机制来解决这些看起来简单的问题,所以「执行上下文
」的概念产生了。
然而,执行上下文是什么?这不得不让我想起组件的模块化开发,之前的一个网页利用代码从上到下一个文件写下来几千行代码,难以浏览、难以保护,所以有了起初的模块化开发。每个模块都有本人的性能,都有属于本人的局部变量和款式。
咱们能够了解为 JavaScript
引擎为了更好的解释和执行代码,所以引入相似于像组件模块的“执行上下文
”的概念用于治理运行时代码的复杂度。
2、执行上下文的分类
上述咱们把形象的“执行上下文”相似于“模块”的具体概念便于了解。当然,执行上下文也就是所谓的“模块”也有不同的分类,在这里具体只开展两种,「全局执行上下文
」和「 部分执行上下文
」。
2.1 全局执行上下文(Global Exception Context)
全局上下文这个“模块”由两局部组成,「全局对象
」和「this
」。
下图是全局执行上下文的最根本模式。蕴含一个 window
对象,以及一个 this
变量,而这个 this
变量是指向 window
对象的,如最右图的打印后果。
从这里咱们看出,执行上下文能够了解为是一个在内存中的「对象和变量
」汇合的模块(或者说是片段),这也是为什么咱们能够把它看作相似“模块”的起因(除此之外还有其余作用)。
小鹿注:为了便于了解,定义是我本人总结的,如有欠缺欢送指出~
2.2 部分执行上下文
部分执行上下文和全局执行上下文相似,但不完全相同,在函数部分执行上下文中,须要留神的有一下两点:
- 函数传入的参数会作为部分执行上下文的变量来存储
- 部分上下文有一个
arguments
参数对象(参考)
部分执行上下文内容会在上面的两个阶段中具体讲到。
3、执行上下文两个阶段
无论是全局执行上下文还是部分的执行上下文,都会经验两个阶段,别离是「创立
」和「 执行
」。
如下咱们有一段代码:
var name = "小鹿";
var age = 23;
function getInfo(){
return {
name: name,
age: age
};
}
3.1 创立阶段(Creation)
创立阶段要实现的事件,如下:
- 在堆内存中创立全局对象(
global object
)—— 浏览器环境是windows
,Node
环境是Global
- 让
this
变量指向这个全局对象 - 设置以后执行上下文中「变量和函数」的内存空间
- 将申明的变量退出内存中(同时挂在到全局对象上),为变量赋值
undifined
,函数存储的是字符串模式
小鹿注:左 (1) 图执行的代码,左 (2) 图创立阶段实现后的执行上下文内存中状态,右 (1) 创立阶段全局对象的状态。
JavaScript
引擎在执行代码之前,先在堆内存中创立全局执行上下文,生成全局对象(global object
),而后让 this
变量指向这个变量。JavaScript
发现代码中申明的两个变量 name
和 age
,而后在全局执行上下文中申请内存空间,将变量存储到该内存空间内,而后为该变量赋值 undefined
,函数就以字符串的模式存储在内存中。
小鹿注:在创立阶段为变量申明指定默认值(
undefined
)的过程称为「变量晋升」。
3.2 执行阶段(Execution
)
全局执行上下文创立实现之后,开始由创立状态(Creation
)变为执行状态(Execution
)。JavaScript
引擎开始逐行运行和执行代码,并为在创立阶段放入内存的变量赋予值。
小鹿注:左 (1) 图执行的代码,左 (2) 图执行阶段实现后的执行上下文内存中状态,右 (1) 执行阶段全局对象的状态。
部分执行上下文和全局执行上下文的创立和执行过程是截然不同的。然而全局执行上下文创立一次,而函数部分执行上下文是随着函数的每次调用都要创立一个部分执行上下文。
还是上述例子,执行后果如下:
var name = "小鹿";
var age = 23;
function getInfo(name){console.log(name);
return {
name: name,
age: age
};
}
getInfo(name);
函数部分上下文执行状态如下:
小鹿注:因为函数中没有定义新的变量,所以在这里没有变量晋升。
咱们理解了什么是函数部分上下文,当函数部分上下文执行结束之后,就会执行出栈操作,将执行权交给父级执行上下文(可能是部分执行上下文,也可能是全局执行上下文),上述 getInfo
函数执行结束的状态如下图所示。
此时的函数执行结束,部分执行上下文出栈销毁,执行权交给全局执行上下文继续执行其余代码。
因为 JavaScript 是单线程的,一次只能执行一个工作,为了不便大伙儿了解,左 (3) 图 是执行栈的调用状况。当然,咱们也能够发现,左 (2) 图是以嵌套的形式来模仿执行栈的操作,每一个嵌套选项都是堆栈中一个新的执行上下文。
4、小结
执行上下文在 JavaScript 中是一个十分重要的概念,在接下几期的进阶文章中,作用域、作用域、闭包、this 等概念,都会与本期文章内容挂钩。力争从原理上了解这些形象的概念。
说点题外话,往年为什么忽然要从最根底的内容写起呢?感觉之前自学备战面试的时候,有些概念尽管记住了,然而没有做到真正的了解和死记硬背,所以打算通过每一期文章,再把之前了解不透彻的这些点都搞清楚。
❤️ 原创不易,欢送素质三连[点赞 + 珍藏 + 评论]
每一期的文章都是工作之外系统工夫整顿而出,波及到一些难懂的概念,会查阅大量的材料和自我思考,难免会呈现一些笔误和有余,也欢送各位读者批评指出~。原创不易,如果感觉不错,心愿点赞多多反对~,咱们下期再见~
我是小鹿,文章同步更新 Github,也能够在微信搜一搜「小鹿动画学编程 」第一工夫接管文章更新告诉,回复“ 前端”可获取小鹿整顿的备战面试小册。