Ch. 1 何謂範疇


編譯器理論

編譯三大步驟

  • Tokenizing (語法基本單元化) 與 Lexing (語彙分析)將一串字元拆解成有意義的組塊 (Tokens),例如將 var a = 2; 拆解為 var、a、=、2、;
  • Parsing (剖析)將 Token 組成樹狀結構 (AST,Abstract Syntax Tree,抽象語法樹)。
  • Code-Generation (產生目的程式碼)將 AST 轉為可執行的程式碼,並做程式的最佳化。

了解範疇

卡司

  • Engine 負責整個編譯過程以及程式碼執行。
  • Compiler 做點髒活,負責處理編譯的三個步驟。
  • Scope 負責收集與維護已宣告的變數,並規範對於目前正在執行的程式碼來說,是否可以取用。

前後往返

var a = 2;
  1. 編譯時:Compiler 會拆解並解析成 AST,但在產生程式碼時,會先詢問 Scope 是否已存在 a 這個變數,若沒有,則請它新增一個。
  2. 執行時:Engine 會詢問 Scope 是否有 a 可以取用,如果沒有會依序往外找,最後若沒有找到,就會大叫出錯了。

Compiler 說話了

查找變數可以分為兩類:

  • LHS:找到變數,作為指定的目標 (e.g. a = 2)。
  • RHS:取回一個值 (e.g. console.log(a) 中的 a 與 console 本身)。

小測驗

function foo(a) {
	var b = a;
		return a + b;
}
var c = foo(2);

LHS:

  1. c =
  2. 隱含的 a = 2
  3. b =

RHS:

  1. foo
  2. = a
  3. a
  4. b

巢狀範疇

範疇可以鑲嵌。在目前執行的範疇找不到變數的時候,Engine 會往外層搜尋,直到找到,或是達到全域為止。

在瀏覽器中,全域就是 window 物件。window 是世界的初始 (無誤)。


錯誤

LHS 與 RHS 查找會帶來不同的錯誤。

ReferenceError:

  • RHS 查找變數失敗時。
  • LHS 查找失敗時,在嚴格模式 (Strict Mode) 下會拋出 ReferenceError,否則,會在全域範圍中自動新增變數。

TypeError:

  • RHS:將不是函式的變數當成函式來宣告,或是在 null 或 undefined 的變數下參考一個屬性 (e.g. var a; a.b)。
  • LHS:重複宣告 const 變數。

複習

  • 解釋 Scope 是什麼。
  • 解釋 LHS 與 RHS。
  • 描述引擎與編譯器在遇到 var a = 2 時,會做哪些動作。
  • LHS 與 RHS 查找時如果找不到會發生什麼事?
  • 描述查找失敗時可能產生的錯誤。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *