- 做者:陳大魚頭
- github: KRISACHAN
- 連接:github.com/YvetteLau/S…
- 背景:最近高級前端工程師 劉小夕 在 github 上開了個每一個工做日佈一個前端相關題的 repo,懷着學習的心態我也參與其中,如下爲個人回答,若是有不對的地方,很是歡迎各位指出。
詞法環境(Lexical Environment) 就是 ECMAScript 的代碼環境。javascript
它由 環境記錄(Environment Record) 和 外部引用 組成。前端
它會根據 ECMAScript 代碼來動態建立。java
環境記錄綁定了其關聯的詞法環境。其一共分了5類,分別以下:git
var
、let
、const
、class
、module
、 import
、function
。詞法環境分了三類:github
null
。全局環境(global environment) 的EnvironmentRecord(環境記錄) 能夠綁定變量,並關聯對應的 全局對象 。super
調用所需的狀態。執行上下文(Execution Contexts) 是 ECMAScript 代碼 運行時(runtime) 的上下文環境。微信
在同一時間內,每次只能有一個 執行上下文(Execution Contexts) 運行。這稱爲 運行執行上下文(running execution context)。前端工程師
執行上下文堆棧(execution context stack) 用於跟蹤 執行上下文(Execution Contexts) 。函數
正在運行的 執行上下文(Execution Contexts) 始終是此堆棧的頂級元素。學習
每當控制從與當前運行的執行上下文相關聯的可執行代碼轉移到與該執行上下文無關的可執行代碼時,就建立新的執行上下文。ui
新建立的執行上下文被壓入堆棧併成爲正在運行的 執行上下文 。
全部執行上下文的狀態組件(State Components)
組件 | 做用 |
---|---|
code evaluation state | 用來判斷當前執行上下文的狀態 |
Function | 判斷當前執行上下文狀態,若是當前上下文是函數,則上下文環境爲此函數對象,不然則爲null |
Realm | 相關代碼從中訪問 ECMAScript 代碼的領域(Realm)記錄。 |
ScriptOrModule | 判斷當前代碼環境,若是沒有所處的腳本或模塊環境,就像在 InitializeHostDefinedRealm (原生方法) 中建立的原始執行上下文的狀況同樣,使上下文環境爲 null 。 |
做用域 負責收集和維護由全部聲明的標識符(變量)組成的一系列查詢,並實施一套很是嚴格的規則,肯定當前執行的代碼對這些標識符的訪問權限。-- 《你不知道的JavaScript(上卷)》
從上面兩個話題,咱們能夠知道,除 全局做用域(global scope) 外,每一個做用域始終鏈接到其背後的一個或多個做用域,從而造成 做用域鏈(scope chain) 。全局做用域(global scope) 沒有任何父級,這也是有意義的,由於它位於層次結構的頂部。
咱們看下面的代碼:
const bestAvenger = "Iron man";
function a() {
const bestActor = "Neymar";
console.log(bestAvenger); // output:Iron man
function c() {
const bestProgrammingLanguage = "Html";
console.log(bestActor); // output:Neymar
b();
}
c();
}
function b() {
console.log(bestProgrammingLanguage); //**not defined error**
}
a();
複製代碼
上面的代碼會報錯以下:bestProgrammingLanguage is not defined.
如上所述,做用域鏈(Scope chain) 始終是 詞法 建立的。做用域 的父節點由 執行上下文(函數) 在代碼中的詞法或物理位置定義。
上面代碼的 做用域鏈(Scope chain) 以下:
詞法環境 | 做用域鏈 |
---|---|
全局做用域下的G | G = G |
G下的A | A = A + G |
G下的B | B = B + G |
G下的A,A下的C | C=C+A => C+A+G |
其實總結起來就是: