顺序执行?
如果要问到 JavaScript 代码执行顺序的话,想必写过 JavaScript 的开发者都会有个直观的印象,那就是顺序执行,毕竟:
然而去看这段代码:
打印的结果却都是两个 foo2
刷过面试题的都知道这是因为 javascript 引擎并非一行一行地分析执行程序,而是一段一段地分析执行。当执行一段代码的时候,会进行一个“准备工作”,比如第一个例子中的变量提升,和第二个例子中的函数提升(下一篇介绍 变量提升跟函数提升)
但是本文真正想让大家思考的是:这个”一段一段“中的”段“究竟是怎么划分的呢?
到底 JavaScript 引擎遇到一段怎样的代码时才会做“准备工作”呢?
可执行代码:
这就要说到 JavaScript 的可执行代码的类型有哪些了?
其实很简单,就三种,全局代码、函数代码、eval代码。
举个例子,当执行到一个函数的时候,就会进行准备工作,这里的“准备工作”,让我们用个更专业一点的说法,就叫做“执行上下文”。
执行上下文栈:
接下来问题来了,我们写的函数多了去了,如何管理创建的那么多执行上下文呢?
所以 JavaScript 引擎创建了执行上下文栈(先进后出)来管理执行上下文。
为了模拟执行上下文栈的行为,让我们定义执行上下文栈是一个数组:
试想当 JavaScript 开始要解释执行代码的时候,最先遇到的就是全局代码,所以初始化的时候首先就会向执行上下文栈压入一个全局执行上下文,我们用 globalContext 表示它,并且只有当整个应用程序结束的时候,ECStack才会被清空,所以 ECStack 最底部永远有个 globalContext:
现在 JavaScript 遇到下面的这段代码了:
当执行一个函数的时候,就会创建一个执行上下文,并且压入到执行上下文栈,当函数执行完毕的时候,就会讲函数的执行上下文从栈中弹出。知道了这样的工作原理,让我们来看看如何处理上面这段代码:
先将遇到的可执行代码推入到栈中,再按照执行顺序去执行代码。 等学完 js 之深入变量对象之后,再来看上一章的理解题