JavaScript | 执行上下文

290 阅读3分钟

前言

本文首发于笔者的个人博客,欢迎围观。

如果在阅读过程发现文章有表达不当的地方,欢迎在评论区指出。

执行上下文

Everything in JavaScript happens inside an Execute Context.

我们可以将执行上下文想象成一个大盒子,在这个盒子里面执行了所有Javascript代码。

将这个盒子看成由两个组件构成,分别是:存储部分以及代码部分

存储部分:即变量环境,其中以键值对的形式存储变量或函数声明。

代码部分:即执行线程,对于其中的代码一次只执行一行。

WEy1lF.png

为什么一次只会执行一行呢?

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 ,值为4return 之后函数执行上下文将会被销毁。

square4 变量的赋值大家可以自行尝试,下图为执行到代码第七行的执行上下文。当代码全部执行完毕后,整个执行上下文将会被销毁。

WEItJJ.png

执行上下文栈

为了管理执行上下文,JavaScript引擎创建了执行上下文栈。

执行过程

  1. JavaScript开始解释上述代码时,初始化的时候先将全局上下文压入执行上下文栈。

WVCjwF.png

  1. line 6: 定义 square2 时调用了 square 函数,创建函数执行上下文,将其压入执行上下文。

    执行结束后,该执行上下文被销毁,所以函数执行上下文也会从执行上下文栈中弹出。

    WVitHO.png

  2. line 7: 与 line6 执行过程类似,不再赘述。

  3. 当所有代码运行结束时,全局执行上下文从执行上下文栈中弹出。

    WVFyW9.png

参阅

How JavaScript Code is executed? | Akshay Saini

JavaScript深入之执行上下文 | 冴羽

小结

JavaScript 所有代码都在执行上下文中执行,而执行上下文栈的出现是为了管理多个执行上下文。

执行上下文可分为代码部分以及存储部分,相对应为执行线程以及变量环境