1. 程式人生 > 實用技巧 >7個你應該知道的 JavaScript 原生錯誤型別

7個你應該知道的 JavaScript 原生錯誤型別

從瀏覽器控制檯到執行 Node.js的終端,我們到處都會看到錯誤。本文的重點是概述我們在js開發過程中可能遇到的錯誤型別。

提示:良好的錯誤提示會導致快速而無痛的發展經歷與緩慢而痛苦的發展經歷之間的區別。在編寫可重用的程式碼時,請確保自己在編寫清晰易懂的錯誤處理程式碼。

1. RangeError

當數字超出允許的值範圍時,將會丟擲此錯誤。

例如

const l = console.logconst arr = [90,88]
arr.length=90**99

我們有一個數組,帶有兩個元素的 arr。接下來,嘗試將陣列擴充套件為包含90**99 == 2.9512665430652753e+193個元素。

這個數字超出了陣列大小可以增長的範圍。執行它會丟擲 RangeError:

$ node errors
errors.js:4
arr.length=90**99
 ^RangeError: Invalid array length

因為我們要增加 arr 陣列的大小超出了 JS 指定的範圍。

2. ReferenceError

當對變數或專案的引用被破壞時,將會引發此錯誤。那是變數或專案不存在。

例如

const l=console.logconst cat = "cat"
cat
dog

有一個變數cat被初始化為 “cat”。接下來引用了cat變數和dog變數。cat變數存在,而dog變數不存在。

cat將返回 “cat”,而dog將引發引用錯誤,因為在環境記錄中找不到名稱dog。

$ node errors
errors.js:3
dog
^ReferenceError: dog is not defined

每當我們建立或定義變數時,變數名稱都會寫入環境記錄中。環境記錄就像鍵值儲存一樣,

+-------------+
| Key | Value |
---------------
| cat | "cat" |
+-------------+

每當我們引用變數時,它都會儲存程式中定義的變數。當在記錄中找到環境值並提取並返回值時,將以該變數的名稱作為關鍵字在環境記錄進行搜尋。呼叫尚未定義的函式。

現在,當我們建立或定義一個沒有賦值的變數時。變數將其鍵作為變數名寫入環境記錄,但其值將會保持未定義的狀態。

var catenv record
+-----------------+
| Key | Value |
-------------------
| cat | undefined |
+-----------------+

稍後為變數分配值時,將在環境記錄中搜索該變數,當發現它未定義值時,該賦值將被覆蓋。

var cat
cat = "cat"env record
+-------------+
| Key | Value |
---------------
| cat | "cat" |
+-------------+

所以當在環境記錄中找不到變數名時,JS 引擎將引發 RefernceError。

+-------------+
| Key | Value |
---------------
| cat | "cat" |
+-------------+cat // "cat", yes, :) it's there
dog // :( what's this? can't find it

注意:未定義的變數不會丟擲 ReferenceError,因為它在於環境記錄中的值尚未設定。

3. SyntaxError

這是最常見的錯誤。當我們輸入 JS 引擎不能理解的程式碼時,就會發生這個錯誤。

JS 引擎在解析期間捕獲了這個錯誤。在 JS 引擎中,我們的程式碼經歷了不同的階段,然後才能在終端上看到結果。

  • 標記化
  • 解析
  • 解釋

標記化將程式碼的源分解為各個單元。在此階段,將對數字、關鍵字、文字、運算子進行分類並分別標記。

接下來,生成的標記流將會傳遞到解析階段,由解析器處理。這是從標記流生成 AST 的地方。 AST 是程式碼結構的抽象表示。

在標記化和解析這兩個階段,如果我們程式碼的語法不符合 JS 的語法規則,則會使該階段失敗並引發 SyntaxError。例如:

constl =console.loglet cat h ="cat"

程式碼中的 “h” 代表什麼?這個 “h” 破壞了程式碼。

$ node errors
errors.js:3
let cat h = "cat"
 ^SyntaxError: Unexpected identifier

看,Node.js 指出了問題的所在。它說 “h” 是意外的,它破壞了cat 變數的宣告。

因此,可以說語法錯誤在解析或編譯期間發生。

4. TypeError

當其他 NativeError 物件中沒有適當的失敗原因的指示時,TypeError 用於指示操作失敗。

對錯誤的資料型別執行操作時會發生 TypeError,例如:

如果我們嘗試將數字轉換為大寫,如下所示:

const num = 123
num.toUpperCase()

這將引發TypeError

$ node errors
errors.js:4
num.toUpperCase()
 ^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。

decodeURI("%")
^URIError: URI malformed

encodeURI用於獲取 URI 的未編碼版本。 “%” 不是正確的 URI,因此引發了URIError。

當 URI 編碼或解碼出現問題時,會引發 URIError。

6. EvalError

當使用全域性eval()函式時,這用於識別錯誤。

根據 EcmaSpec 2018 版:

此規範當前未使用此異常。保留它目的是為了與本規範的先前版本相容。

佛山vi設計https://www.houdianzi.com/fsvi/ 豌豆資源搜尋大全https://55wd.com

7. InternalError

該錯誤在 JS 引擎內部發生,特別是當它有太多資料要處理並且棧增長超過其關鍵限制的時侯。

當 JS 引擎被過多的遞迴和切換情況等淹沒時,就會發生這種問題

switch(num) {
 case 1:
 ...
 break
 case 2:
 ...
 break
 case 3:
 ...
 break
 case 4:
 ...
 break
 case 5:
 ...
 break
 case 6:
 ...
 break
 case 7:
 ...
 break
 ... up to 1000 cases
 }

以下是一個簡單的過多遞迴的例子:

function foo() {
    foo()
}
foo()

總結

正如我們所說,誰都會犯錯誤。就我們敲程式碼這件事而言,這是一個穩定的事件。為了克服它,我們需要知道可以丟擲的原生錯誤的型別。本文中列出了它們,並提供了一些示例來說明它們是如何引發的。

所以無論什麼時候在終端或瀏覽器中引發錯誤,你都可以輕鬆發現錯誤產生的位置和方式,並能夠編寫更好、更不易出錯的程式碼。