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,那么他就会:

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

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

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

并且,它们各自包含了 创造阶段 creation phase 和 执行阶段 execution phase,
所以这边先画个简表,我们现在有的资讯大概长这样:
http://img2.58codes.com/2024/20129476Lne8evQG1H.png

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

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

Global Execution Context


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

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

http://img2.58codes.com/2024/20129476UaNgShWsEt.png

创建 global object。( 如浏览器中的window object,或Node.js中的 global object。)建立 scope (依照 closure 这个準则)。创建 this object,并被绑定至 global object。将 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 的状态如下:

objectvalue备注global objectwindow因为在浏览器里执行,因此global object 为 windowthiswindow这时的this也指向 window objectaundefinedareafunction(){...}bundefined

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

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

http://img2.58codes.com/2024/20129476EODl3Rl0mw.png

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

let a = 3;  // a = 3function 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 的状态:

objectvalueglobal objectwindowthiswindowa3areafunction(){...}bundefined

到这里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 :

http://img2.58codes.com/2024/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 会变成下列的状态:

objectvalueglobal objectargumentsthiswindowsundefined

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

然后进到 Function Execution Context 的 execution phase :

objectvalueglobal objectargumentsthiswindows3

最后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 资料结构。而资料结构就是之后文章的範畴了!


最后~

帮今天的文章画重点:

Execution context即为程式码创造物件到执行的过程过程分为 Global EC 和 Function EC 两种。两者的区别为: 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 phaseE. = execution phase

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

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

---正文结束---

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


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章