atexit函数的执行顺序_JavaScript深入之执行上下文栈

顺序执行?

如果要问到 JavaScript 代码执行顺序的话,想必写过 JavaScript 的开发者都会有个直观的印象,那就是顺序执行,毕竟:

1383953ef306667d265d93becba46ed4.png

c66652801caa7e8880105019207e709b.png

然而去看这段代码:

a269464c87242bc910205f31cd2432a3.png

410cd8848c8a3edc0b01b503d073d221.png

打印的结果却都是两个 foo2

刷过面试题的都知道这是因为 javascript 引擎并非一行一行地分析执行程序,而是一段一段地分析执行。当执行一段代码的时候,会进行一个“准备工作”,比如第一个例子中的变量提升,和第二个例子中的函数提升(下一篇介绍 变量提升跟函数提升)

但是本文真正想让大家思考的是:这个”一段一段“中的”段“究竟是怎么划分的呢?

到底 JavaScript 引擎遇到一段怎样的代码时才会做“准备工作”呢?


可执行代码:

这就要说到 JavaScript 的可执行代码的类型有哪些了?

其实很简单,就三种,全局代码、函数代码、eval代码。

举个例子,当执行到一个函数的时候,就会进行准备工作,这里的“准备工作”,让我们用个更专业一点的说法,就叫做“执行上下文”。


执行上下文栈:

接下来问题来了,我们写的函数多了去了,如何管理创建的那么多执行上下文呢?

所以 JavaScript 引擎创建了执行上下文栈(先进后出)来管理执行上下文。

为了模拟执行上下文栈的行为,让我们定义执行上下文栈是一个数组:

566acee47ee0f6c38be6ceb8b2ee7aef.png

试想当 JavaScript 开始要解释执行代码的时候,最先遇到的就是全局代码,所以初始化的时候首先就会向执行上下文栈压入一个全局执行上下文,我们用 globalContext 表示它,并且只有当整个应用程序结束的时候,ECStack才会被清空,所以 ECStack 最底部永远有个 globalContext:

0709c5efae2a51901ecdb8135045c4c2.png

35434a5891438a671277f9598c629aa8.png

现在 JavaScript 遇到下面的这段代码了:

ee8688fdbdee05a0a06216f082677ce5.png

当执行一个函数的时候,就会创建一个执行上下文,并且压入到执行上下文栈,当函数执行完毕的时候,就会讲函数的执行上下文从栈中弹出。知道了这样的工作原理,让我们来看看如何处理上面这段代码:

ebe062b686346663fb41fea429ecdb1b.png

先将遇到的可执行代码推入到栈中,再按照执行顺序去执行代码。 等学完 js 之深入变量对象之后,再来看上一章的理解题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值