前言
本文首发于笔者的个人博客,欢迎围观。
如果在阅读过程发现文章有表达不当的地方,欢迎在评论区指出。
执行上下文
Everything in JavaScript happens inside an Execute Context.
我们可以将执行上下文想象成一个大盒子,在这个盒子里面执行了所有Javascript代码。
将这个盒子看成由两个组件构成,分别是:存储部分以及代码部分。
存储部分:即变量环境,其中以键值对的形式存储变量或函数声明。
代码部分:即执行线程,对于其中的代码一次只执行一行。
为什么一次只会执行一行呢?
JavaScript 是一门同步单线程语言
单线程:JavaScript一次只能执行一个命令。
同步单线程:JavaScript一次只执行一个命令并以特定顺序执行。
下面我们通过实例来了解,执行上下文是如何处理JavaScript程序的。
实例分析(图解)
var n = 2
function square (num) {
var ans = num * num
return ans
}
var square2 = square(n)
var square4 = square(4)
全局变量的执行上下文
变量环境
line 1: 声明变量 n
,值为 undefined
line 2-5: 声明函数 square
,值为 {...}
line 6: 声明变量 square2
,值为 undefined
line 7: 声明变量 square4
,值为 undefined
执行线程
line 1: 将 2
赋值给 n
line 6, 7: 调用了 square
函数,进入函数的执行上下文
square函数的执行上下文
变量环境
line 2: 声明变量 num
,值为 undefined
line 3: 声明变量 ans
,值为 undefined
执行线程
line 6: 将全局变量 n
的值赋给 num
,值为 2
line 3: 将 ans
赋值为 num * num
, 值为 4
line 4: 返回 ans
,将 ans
的值赋给全局变量 square2
,值为4
;return
之后函数执行上下文将会被销毁。
square4
变量的赋值大家可以自行尝试,下图为执行到代码第七行的执行上下文。当代码全部执行完毕后,整个执行上下文将会被销毁。
执行上下文栈
为了管理执行上下文,JavaScript引擎创建了执行上下文栈。
执行过程
- JavaScript开始解释上述代码时,初始化的时候先将全局上下文压入执行上下文栈。
-
line 6: 定义
square2
时调用了square
函数,创建函数执行上下文,将其压入执行上下文。执行结束后,该执行上下文被销毁,所以函数执行上下文也会从执行上下文栈中弹出。
-
line 7: 与
line6
执行过程类似,不再赘述。 -
当所有代码运行结束时,全局执行上下文从执行上下文栈中弹出。
参阅
How JavaScript Code is executed? | Akshay Saini
小结
JavaScript 所有代码都在执行上下文中执行,而执行上下文栈的出现是为了管理多个执行上下文。
执行上下文可分为代码部分以及存储部分,相对应为执行线程以及变量环境。