你應該知道的7 個 JavaScript 原生錯誤類型
- 2020 年 3 月 13 日
- 筆記
從瀏覽器控制台到運行 Node.js 的終端,我們到處都會看到錯誤。
本文的重點是概述我們在 JS 開發過程中可能遇到的錯誤類型。
1. RangeError
當數字超出允許的值範圍時,將會拋出此錯誤。
例如
1const l = console.logconst arr = [90,88] 2arr.length=90**99
我們有一個數組,帶有兩個元素的 arr。接下來,嘗試將數組擴展為包含 90**99 == 2.9512665430652753e+193
個元素。
這個數字超出了數組大小可以增長的範圍。運行它會拋出 RangeError:
1$ node errors 2errors.js:4 3arr.length=90**99 4 ^RangeError: Invalid array length
因為我們要增加 arr 數組的大小超出了 JS 指定的範圍。
2. ReferenceError
當對變數或項目的引用被破壞時,將會引發此錯誤。那是變數或項目不存在。
例如
1const l=console.logconst cat = "cat" 2cat 3dog
有一個變數 cat
被初始化為 「cat」。接下來引用了 cat
變數和 dog
變數。cat
變數存在,而 dog
變數不存在。
cat
將返回 「cat」,而 dog
將引發引用錯誤,因為在環境記錄中找不到名稱 dog
。
1$ node errors 2errors.js:3 3dog 4^ReferenceError: dog is not defined
每當我們創建或定義變數時,變數名稱都會寫入環境記錄中。環境記錄就像鍵值存儲一樣,
1+-------------+ 2| Key | Value | 3--------------- 4| cat | "cat" | 5+-------------+
每當我們引用變數時,它都會存儲程式中定義的變數。當在記錄中找到環境值並提取並返回值時,將以該變數的名稱作為關鍵字在環境記錄進行搜索。調用尚未定義的函數。
現在,當我們創建或定義一個沒有賦值的變數時。變數將其鍵作為變數名寫入環境記錄,但其值將會保持未定義的狀態。
1var catenv record 2+-----------------+ 3| Key | Value | 4------------------- 5| cat | undefined | 6+-----------------+
稍後為變數分配值時,將在環境記錄中搜索該變數,當發現它未定義值時,該賦值將被覆蓋。
1var cat 2cat = "cat"env record 3+-------------+ 4| Key | Value | 5--------------- 6| cat | "cat" | 7+-------------+
所以當在環境記錄中找不到變數名時,JS 引擎將引發 RefernceError。
1+-------------+ 2| Key | Value | 3--------------- 4| cat | "cat" | 5+-------------+cat // "cat", yes, :) it's there 6dog // :( what's this? can't find it
注意:未定義的變數不會拋出 ReferenceError,因為它在於環境記錄中的值尚未設置。
3. SyntaxError
這是最常見的錯誤。當我們輸入 JS 引擎不能理解的程式碼時,就會發生這個錯誤。
JS 引擎在解析期間捕獲了這個錯誤。在 JS 引擎中,我們的程式碼經歷了不同的階段,然後才能在終端上看到結果。
- 標記化
- 解析
- 解釋
標記化將程式碼的源分解為各個單元。在此階段,將對數字、關鍵字、文字、運算符進行分類並分別標記。
接下來,生成的標記流將會傳遞到解析階段,由解析器處理。這是從標記流生成 AST 的地方。AST 是程式碼結構的抽象表示。
在標記化和解析這兩個階段,如果我們程式碼的語法不符合 JS 的語法規則,則會使該階段失敗並引發 SyntaxError。例如:
1const l = console.loglet cat h = "cat"
程式碼中的 「h」 代表什麼?這個 「h」 破壞了程式碼。
1$ node errors 2errors.js:3 3let cat h = "cat" 4 ^SyntaxError: Unexpected identifier
看,Node.js 指出了問題的所在。它說 「h」 是意外的,它破壞了cat 變數的聲明。
因此,可以說語法錯誤在解析或編譯期間發生。
4. TypeError
當其他 NativeError 對象中沒有適當的失敗原因的指示時,TypeError 用於指示操作失敗。
對錯誤的數據類型執行操作時會發生 TypeError,例如:
如果我們嘗試將數字轉換為大寫,如下所示:
1const num = 123 2num.toUpperCase()
這將引發TypeError
1$ node errors 2errors.js:4 3num.toUpperCase() 4 ^TypeError: num.toUpperCase is not a function
因為 toUpperCase
函數需要字元串數據類型。toUpperCase
函數是有意通用的;它不需要其 this
值是 String
對象。因此,可以將其轉移到其他種類的對象中用作方法。
只有字元串才會轉換為大寫或小寫形式,如果我們在 Objects、Boolean、Symbol、null、undefined 數據類型上調用 toUpperCase
函數,則將會得到 TypeError,因為它操作的數據類型錯誤。
5. URIError
這表明使用了一種與其定義不兼容的全局 URI 處理函數。
JS 中的 URI(統一資源指示符)具有以下功能:decodeURI、decodeURIComponent 等。
如果我們用錯誤的參數去調用其中任何一個,將得會到一個 URIError。
1decodeURI("%") 2^URIError: URI malformed
encodeURI
用於獲取 URI 的未編碼版本。「%」 不是正確的 URI,因此引發了URIError。
當 URI 編碼或解碼出現問題時,會引發 URIError。
6. EvalError
當使用全局 eval()
函數時,這用於識別錯誤。
根據 EcmaSpec 2018 版:
此規範當前未使用此異常。保留它目的是為了與本規範的先前版本兼容。
7. InternalError
該錯誤在 JS 引擎內部發生,特別是當它有太多數據要處理並且棧增長超過其關鍵限制的時侯。
當 JS 引擎被過多的遞歸和切換情況等淹沒時,就會發生這種問題
1switch(num) { 2 case 1: 3 ... 4 break 5 case 2: 6 ... 7 break 8 case 3: 9 ... 10 break 11 case 4: 12 ... 13 break 14 case 5: 15 ... 16 break 17 case 6: 18 ... 19 break 20 case 7: 21 ... 22 break 23 ... up to 1000 cases 24 }
以下是一個簡單的過多遞歸的例子:
1function foo() { 2 foo() 3} 4foo()
總結
正如我們所說,誰都會犯錯誤。就我們敲程式碼這件事而言,這是一個穩定的事件。為了克服它,我們需要知道可以拋出的原生錯誤的類型。本文中列出了它們,並提供了一些示例來說明它們是如何引發的。
所以無論什麼時候在終端或瀏覽器中引發錯誤,你都可以輕鬆發現錯誤產生的位置和方式,並能夠編寫更好、更不易出錯的程式碼。
原文鏈接
https://blog.bitsrc.io/types-of-native-errors-in-javascript-you-must-know-b8238d40e492