六角學院 JS 核心筆記 (二)【執行環境與作用域】- 執行的錯誤情境 LHS、RHS

JS 直譯過程

在直譯的過程中,JavaScript 引擎、編譯器和範疇會互相溝通以完成工作。它們各自負責的任務有:

  • JavaScript 引擎:負責整個編譯過程並執行程式碼。
  • 編譯器:負責編譯三步驟-語法基本單元化與語彙分析、剖析或稱語法分析、產生目的程式碼。
  • 範疇:負責維護變數 (Identifier) 清單。編譯器或 JavaScript 引擎在編譯期間執行期間查找變數時會有一套規則。

LHS、RHS

編譯器 (編譯期間) 或 JavaScript 引擎 (編譯期間和執行期間) 查找變數的動作,可分為兩種類型:

  • LHS (Left-hand side):要查找的變數在指定動作 = 的左邊,就是執行 LHS 查找動作。編譯時就會報錯。
    • var ming = “小明”;
  • RHS (Right-hand side):要查找的變數不在指定動作 = 的左邊,就是執行 RHS 查找動作。執行時才會報錯。
    • console.log(ming);
    • var man = ming; (這一行的 ming)

LHS、RHS 錯誤

為什麼需要理解 LHS 和 RHS 呢?這是因為要看懂 JavaScript 報錯的原因。當解析 identifier 失敗時,依照 LHS 或 RHS 錯誤,環境會丟出不同錯誤訊息。

若是 LHS 錯誤,就會分為是否在嚴格模式(strict mode)的情況

  • 在非嚴格模式下,會在全域建立這個變數。

    • 例如:我們直接在瀏覽器的開發者工具中的 Console 中輸入 b = 2; 因為是在非嚴格模式下,所以不用加 var 也不會報錯,會直接在全域建立變數 b
  • 在嚴格模式下,會丟出 Uncaught SyntaxError 的訊息。

    • 例如:在 Console 中輸入 var '小明' = 1; 或是 '小明' = 1;,因為在查找 = 左邊的 identifier 時就出現錯誤,會丟出 Uncaught SyntaxError: ...

若是 RHS 錯誤,則會丟出 Uncaught ReferrenceError 的訊息。

  • 例如:在尚未定義 ming 時,直接將其指派給某一變數,則會出現 Uncaught ReferrenceError: ...

其他錯誤

還有一種狀況,不論在 LHS 和 RHS 下,操作不合法的行為時,就會丟出 TypeError 的訊息。

  • LHS:重新設定已宣告為 const 變數,const a = 2; a = 4;a = 4; 會導致 TypeError。

  • RHS:執行不是 function 的變數,const b = 2; b();b(); 會導致 TypeError。

參考資料:
六角學院:JavaScript 核心篇 - 邁向達人之路
你懂 JavaScript 嗎?#10 範疇(Scope)
你不知道的JavaScript LHS 和 RHS 查詢