JavaScript执行上下文和执行栈结合
对于我们前端开发者来说理解JS
程序内部执行机制是必要的,其中一个关键概念就是Js
的执行上下文和执行栈。执行上下文是JS
语言较为底层的知识,学习掌握有助于我们更深入的把握JS
这门语言的本质,也有助于理解作用域、闭包、变量提升等相关知识。
1 何为执行上下文
代码执行前,浏览器的Js
引擎先会创建代码执行的环境来处理此Js
代码的转换和执行,代码的执行环境称为执行上下文。
执行上下文是一个抽象概念,包含当前正在运行的代码以及帮助其执行的所有内容。
2 分类
执行上下文主要分为三类:
- 全局执行上下文 —— 全局代码所处的环境,不在函数内部代码都在全局执行。
- 函数执行上下文 —— 在函数调用时创建的上下文。
Eval
执行上下文 —— 运行在Eval
函数中代码时创建的环境,Eval
由于性能问题在我们平时开发中很少用到,所有这里我们不在讨论。
接下来我们重点来讲全局上下文和函数上下文。
2.1 全局执行上下文
当我们的JS
文件跑起来之后,首先创建的就是全局执行上下文。
当我们的文件里没有一行代码时,全局执行上下文中比较干净,只有两个东西。
- 全局对象(浏览器里是
Window
,Node
环境下是Global
) this
变量(指向的还是全局对象)
这时候如果我们在文件里写点东西,比如我写如下代码:
var name = '小明'
var age = 18
function showName(){
return {
name : name,
age : age
}
}
全局执行上下文就会立刻变成这个样子:
上图可以看到,我们明明给name
和age
赋值了,咋还会显示undefined
呢?这是因为执行上下文分为两部分,创建阶段和执行阶段。
- 创建阶段 —— 执行上下文的初始化状态,做一些准备工作
- 执行阶段 —— 代码一行一行执行
- 将
window
作为全局执行上下文对象 - 创建
this
,this
指向window
- 给变量和函数安排内存空间
- 变量赋值
undefined
,函数声明放入内存 - 放入作用域链
接下来才会进入了全局执行上下文的执行阶段,也就是赋值阶段,如下图:
需要注意的是执行上下文执行阶段是一行一行执行的,如下图所示:
2.2 函数执行上下文
理解完全局执行上下文,函数执行上下文也我们只需要关注它与全局上下文之间的不同即可,两者之间不同主要表现在以下三个方面:
- 创建时机:全局执行上下文在执行JS文件之前就被创建,而函数执行上下文则是在函数调用时创建。
- 创建频率:全局上下文在代码刚开始被执行前创建一次,而函数执行上下文由脚本里函数调用次数决定,可以创建无数次。
- 创建内容:全局执行上下文将
window
作为全局对象,而是函数执行上下文则是创建参数对象arguments
;创建的this
也不会指向全局对象,而是取决于函数是如何调用的。
我们通过下面这个例子来看函数上下文不同阶段的表现:
var name = '小明'
var age = 18
function showName(){
return {
name : name,
age : age
}
}
// 调用该函数
showName()
当我们调用showName
函数时,就会进入到函数执行上下文的创建阶段,函数执行上下文的场景如下:
接着就会进入到执行阶段,这个阶段函数内代码才会一行一行执行,这个例子中,因为没有涉及到变量的修改,因此函数上下文的内容保持不变,执行完毕后,函数上下文的生命周期就结束了。
当我们调用showName
函数时,在浏览器中运行状况:
3 执行栈
我们看到当函数执行完后,其对应的执行上下文也随之消失了。这个消失的过程,我们叫它出栈——在JS
代码执行过程中,JS
引擎会为我们创建“执行上下文栈”。
在全局代码执行前,JS
引擎为了管理执行上下文,确保程序的执行顺序。JS
引擎会创建一个栈来管理所有的所有的执行上下文对象。
因为函数上下文可能会存在多个,我们不可能保留所有的上下文。当一个函数执行完毕,其对应的上下文必须让出之前所占用的资源。因此上下文的建立和销毁,就对应了一个” 入栈 “和” 出栈 “的操作。
当我们调用一个函数的时候,就会把它的上下文推入调用栈里,执行完毕后出栈,随后再为新的函数进行入栈操作。
我们通过一个例子来看一下这个过程:
function testA(){
console.log('执行第一个测试函数的逻辑');
testB();
console.log('再次执行第一个测试函数的逻辑');
}
function testB(){
console.log('执行第二个测试函数的逻辑');
}
testA()
1、执行之前,全局上下文创建:
2、testA
调用,testA
对应函数上下文创建:
3、testB
调用,testB
对应函数上下文创建:
4、testB
执行完毕,对应上下文出栈,剩下testA
和全局执行上下文:
5、testA
执行完毕,对应执行上下文出栈,此时只剩下全局上下文:
在这整个过程里,调用栈的变化示意如下:
4 总结
-
执行上下文是什么:代码执行前,Js引擎会创建代码的执行环境,代码的执行环境称作执行上下文,包含当前正在运行的代码以及帮助其执行的所有内容。
-
全局执行上下文:(1)将window作为全局执行上下文对象(2)创建this,this 指向window(3)给变量和函数安排内存空间(4)变量赋值undefined,函数声明放入内存(5)放入作用域链
-
全局与函数执行上下文不同:(1)全局:在文件执行前创建;函数:在函数调用时创建(2)全局:只创建一次;函数:调用几次创建几次(3)将window作为全局对象;函数:创建参数对象arguments,this指向调用者
-
执行栈:管理所有的执行上下文对象
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanfieji
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01