D7 - 你不知道Combo: 第二主菜 Execution Context

前言

JavaScript 可以随时随地呼叫函式,像 function A 呼叫了 function B,执行完 function B 又回到 function A,不禁好奇想问,引擎是怎麽知道该执行哪个 function、顺序谁先谁後?

吃完这第二道主菜 执行背景空间 Execution Context(EC) 你就懂了,上菜!

执行背景空间 Execution Context

在 JavaScript 执行程序时,其实都是在一个 Execution Context 执行背景空间内进行,函式是最基本的执行单位,每个 function 都有一个背景执行空间,函式背景空间分为两种:

  1. 全域背景执行空间

全域的背景执行空间只会有一个,以下称 全域 EC

  1. 函式执行背景空间

而每次呼叫 function 就会创立一个新的函式执行背景空间,以下称 function EC

好的,那创立了这麽多个 EC,怎麽决定谁先执行?
JavaScript 是单执行绪的语言,一次只能做一件事,总不会每次都靠剪刀石头布决定吧。

一个最简单的方法就是,将每个 EC 像乐高般一个个堆叠排好,从最顶端开始拿,新加入的 EC 再继续堆叠放上去,执行完毕就把它拿下来,他们堆叠的地方称为 Execution Context Stack  或更常被称呼为  呼叫堆叠 Call Stack


图片取自CLEANPNG

呼叫堆叠 Call Stack

Call Stack 内会堆叠着一个个 EC,协助引擎追踪所有待执行的函式,呼叫一个 function 就会有一个新的 EC 被创造,并放入 Call Stack 中,待结束再从堆叠中弹出。

通常会说 push 放入、pop 弹出(好嫩Q)

在一些文章中会看到一个专有名词 LIFO(Last-in-first-out)後进先出,用来表示比较晚放入 Call Stack 的 EC,执行完毕後会先 pop 弹出

「嘿,菜鸟结束快闪。」

举一个例子实际来看看

function getCookie(cookie){
    console.log(cookie);
}

function afternoonTea (biscuit){
  getCookie(biscuit)
}

afternoonTea ('Oreo');

上面的程序码定义了两个 function,第 1 个 function getCookie 会印出 cookie,第 2 个 function afternoonTea 会呼叫第 1 个 function getCookie

让我们来呼叫function afternoonTea 看看 Call Stack 是怎麽堆叠的?

  1. 开始执行程序,这时全域 EC 被创造出来,并放入 Call Stack 内
  2. 呼叫 function afternoonTea,一个新的 EC 被创造然後放入 Call Stack 的顶端
  3. 开始执行 afternoonTea 内呼叫 function getCookie 的动作,又一个新的 EC 被创造出来放入 Call Stack 顶端,执行 getCookie 印出 'Oreo'
  4. 当执行完 getCookie,它的 EC 会从 Call Stack 中弹出,这时最顶端的 EC 是 afternoonTea,很好,引擎知道再来该执行谁
  5. afternoonTea 执行完毕也被弹出,这时 Call Stack 剩下一个全域 EC,当全域内的程序执行完毕後弹出,掰掰,没有任何待执行的 EC 在 Call Stack 中,执行完毕!

以上就是 Call Stack 执行的结果,依照程序码执行的过程不断有 EC 被 push 进又 pop 出,直到 Call Stack 内不再有任何 EC,程序也就执行完毕。

和 Lexical Environment 的关系?

以上撷自 ECMA 9.4 Execution Context 的内容,提到了 字汇环境 Lexical Environment 是 EC 的一个 component,执行背景空间 EC 可以透过 字汇环境 Lexical environment 来解析识别项,就是查找所有的变数及 function 的动作。
哇!与前一道菜的观念串起来了呢,所以有些文章讲 Hoisting 时会从 EC 讲起,因为 EC 都有自己相关联的字汇环境存放变数、参数及 function 值的地方。

结语

本来还想继续讲执行背景空间 Execution Context 与 字汇环境 Lexical Environment 的图例,但昨天接到食客反应篇幅太长吃到快吐,决定这部分留到 Closure 的时候再继续吧!
~少量多餐有益健康~

Reference:

书籍:
你所不知道的JS  by Kyle Simpon
忍者 JavaScript 开发技巧探秘第二版  by John Resig, Bear Bibeault, Josip Maras

文章:
The JavaScript Call Stack
我知道你懂 hoisting,可是你了解到多深?
ECMA
JavaScript Execution Context


<<:  D21-(9/21)-长荣(2603)-你只要懂海,海就会帮你

>>:  [Day-13] 条件运算子以及switch小练习

学习日记-2

有一小段时间没跟新了XD! 主要是平时都加班,下班去健身房回到家,就只剩1-2小时的学习时间,就慢慢...

day3: 程序码的命名 (component, className)

在 react 的命名原则中,除了 component 和 type 是 Pascal Case,其...

Day 26 Wireless Attacks - 无线攻击 (aircrack-ng)

前言 终於进入新的篇章06-Wireless Attacks,但由於先前的Kali虚拟机环境无法进行...

Day 10:Component, Component, Component

前面的文章匆忙带过 MainWindow,建议从官方的文件再深入理解 JUCE Applicatio...

Day 03 Azure Virtual Machine- Windows 使用者的救星

Azure Virtual Machine- Windows 使用者的救星 有些新手的电脑安装的作业...