JavaScript的执行阶段: Execution Context

为了知道那些常被拿来考观念的专有名词是哪里来的,
这篇要先整理 JS的 Execution Context!

Execution Context 的定义


『当JS引擎执行一段程序码(script)时,便会创造 execution contexts。』
『且每个execution context 包含两个阶段:创造阶段 creation phase执行阶段 execution phase。』

引用自JavaScript Tutorial Website的解释:

When a JavaScript engine executes a script, it creates execution contexts. Each execution context has two phases: the creation phase and the execution phase.
(引用自 JavaScript Execution Context )

→ 也就是说,Execution contexts 包含了程序码 创造物件 到 执行 的过程。

到这里先记一个结论,接下来先继续看实际上发生了什麽事。

Execution Context 的执行过程


所以Execution Context到底在做什麽?

在执行过程中,JS里的物件会被初始化和给值。

假设现在JS要执行一个script,那麽他就会:

  1. 先产生Execution Context
  2. 进入创造阶段 creation phase
  3. 完成creation phase,进入执行阶段 execution phase。

在刚刚提到的定义里,可以发现定义里的execution context"s"是复数形,
由此可知会产生的execution context其实不只有一个,而程序码会执行的execution context分为两种:

  • Global Execution Context ( *Global 全域
  • Function Execution Context ( *Function 函数

并且,它们各自包含了 创造阶段 creation phase执行阶段 execution phase
所以这边先画个简表,我们现在有的资讯大概长这样:
https://ithelp.ithome.com.tw/upload/images/20210902/20129476Lne8evQG1H.png

而我们学习目标,就是要知道这段过程,哪个物件先创造? 什麽时候被指派? 被指派给谁?

知道重点是什麽就可以往下看了~

Global Execution Context


初次 执行一个script时,JS引擎会创造第一种 execution context,叫 Global Execution Context。

然後先进入 创造阶段 creation phase :

https://ithelp.ithome.com.tw/upload/images/20210903/20129476UaNgShWsEt.png

  1. 创建 global object。( 如浏览器中的window object,或Node.js中的 global object。)
  2. 建立 scope (依照 closure 这个准则)。
  3. 创建 this object,并被绑定至 global object。
  4. variablesfunction 分配至记忆体,并初始化为 undefined。
    (这也是所谓的hoisting。)

讲太多抽象的概念不好理解,让我们假设一个求面积的程序码范例:

let a = 3;

function area(s){
    return s * s;
}

let b = area(a);

console.log(b);

在这个阶段,各object会被初始化,也就是程序码会知道有这个object存在,但变数还不会被赋值。
因此 Global Execution Context在 creation phase 的状态如下:

object value 备注
global object window 因为在浏览器里执行,因此global object 为 window
this window 这时的this也指向 window object
a undefined
area function(){...}
b undefined

接着,Global Execution Context 会来到 执行阶段 execution phase:

这时JS的script便会逐行被执行,对variables给值,并执行function的呼叫(call)。

https://ithelp.ithome.com.tw/upload/images/20210903/20129476EODl3Rl0mw.png

( 补充 : JS是直译式语言的一种,而直译式语言的特色就是「逐行( line by line )」执行。相对於编译式语言「先编译再执行」的方式。)

let a = 3;  // a = 3

function area(s){
    return s * s;
}

let b = area(a); // 调用area(a)

console.log(b);

延续上方的例子,程序码会逐行进行给值,因此a会被先assign为3,
接着要assign值给b,就必须进行function call,调用函数area()。

目前 Global Execution Context 在 execution phase 的状态:

object value
global object window
this window
a 3
area function(){...}
b undefined

到这里Global scope会先停下来,
然後进入到Function Execution Context的creation phase...

2. Function Execution Context


JS会创造复数的Execution Context,而第二种就是Function Execution Context。
而每次的 function call ,JS引擎也都会创造一个Function Execution Context。

Function Execution Context 的 创造阶段 creation phase :

https://ithelp.ithome.com.tw/upload/images/20210903/20129476AUAToO6Tiw.png

和 Global Execution Context 的区别,引用文献解释的比较清楚 :

The Function Execution Context is similar to the Global Execution Context, but instead of creating the global object, it creates the arguments object that contains a reference to all the parameters passed into the function.
(引用自 JavaScript Execution Context )

简而言之,Execution Context在 creation phase 创造的不是window,而是欲传进函式的参数arguments物件。

於是我们在 Function Execution Context 在 creation phase 会变成下列的状态:

object value
global object arguments
this window
s undefined

因为已经是Function Execution Context,global object会变为arguments,而参数s则被初始化为undefined。

然後进到 Function Execution Context 的 execution phase :

object value
global object arguments
this window
s 3

最後area(s)计算完成,便会回传数值并assign给 b。

let a = 3;

function area(s){
    return s * s;
}

let b = area(a);

console.log(b);  // output: 9

从上面的叙述中,可以知道执行程序码的时候创造了非常多的execution contexts,无论是Global EC或 Function EC 的执行,都会遵照被称为 Call stack 资料结构。而资料结构就是之後文章的范畴了!


最後~

帮今天的文章画重点:

  1. Execution context即为程序码创造物件到执行的过程
  2. 过程分为 Global EC 和 Function EC 两种。
  3. 两者的区别为: Global EC创造的Global Object为window,Function EC创造的Global Object则为arguments

我写了一张简表,记忆JS的Execution Context执行和object的创建顺序。

Global EC

C. window obj. → scope ( follow closure ) → this → Hoisting
E. follow Call stack

Function EC

C. scope chain → this → Hoisting
E. follow Call stack

  • EC = Execution Context.
  • C. = creation phase
  • E. = execution phase

之後整理专有名词就可以更了解各个阶段会出什麽事了

【如内文有误还请不吝指教>< 并感谢阅览至此的各位:D 】

---正文结束---

这篇是在发scope之前打好的,考虑了一下要不要跟铁人赛发在一起,但实在太文不对题了所以还是独立成一篇。
我觉得,发表文章在所有人都能看见的地方,是件蛮需要勇气的事:(敬佩这里所有的作者。


<<:  2.移转 Aras PLM大小事-拆解Agile的准备工作

>>:  建立 Google App Script 专案(1)

[ 卡卡 DAY 8 ] - React Native 跨平台装置判断

还记得 React Native 可以同时完成 iOS / Android 装置吧? 跨平台装置如...

在 Clear Linux 上安装 VirtualBox 6.1.26

前言 我是先把 Kernel 等相关套件,以及 VirtualBox 安装起来之後,再从错误讯息去尝...

Sass @mixin实现RWD DAY36

今天我们要来介绍 Sass Mixin 与 content的搭配 来解决RWD Scss: @mix...

Day 01 「科学 v.s. 数学」前言

笔者从业数年,面试过不少程序开发者。每当问到对方是否有做单元测试时,绝大多数的面试者总会说: 「我知...

Day5 Next.js 介绍 - Production-ready 的 React.js 框架

这系列内容主要内容是在讲如何用 Next.js 取代 WordPress 前端,因此约 70% 内容...