7個(gè)你應(yīng)該知道的JS原生錯(cuò)誤類(lèi)型
概述
從瀏覽器控制臺(tái)到運(yùn)行 Node.js的終端,我們到處都會(huì)看到錯(cuò)誤。本文的重點(diǎn)是概述我們?cè)趈s開(kāi)發(fā)過(guò)程中可能遇到的錯(cuò)誤類(lèi)型。
提示:良好的錯(cuò)誤提示會(huì)導(dǎo)致快速而無(wú)痛的發(fā)展經(jīng)歷與緩慢而痛苦的發(fā)展經(jīng)歷之間的區(qū)別。在編寫(xiě)可重用的代碼時(shí),請(qǐng)確保自己在編寫(xiě)清晰易懂的錯(cuò)誤處理代碼。
1. RangeError
當(dāng)數(shù)字超出允許的值范圍時(shí),將會(huì)拋出此錯(cuò)誤。
例如
const l = console.logconst arr = [90,88] arr.length=90**99
我們有一個(gè)數(shù)組,帶有兩個(gè)元素的 arr。接下來(lái),嘗試將數(shù)組擴(kuò)展為包含90**99 == 2.9512665430652753e+193個(gè)元素。
這個(gè)數(shù)字超出了數(shù)組大小可以增長(zhǎng)的范圍。運(yùn)行它會(huì)拋出 RangeError:
$ node errors
errors.js:4
arr.length=90**99
^RangeError: Invalid array length
因?yàn)槲覀円黾?arr 數(shù)組的大小超出了 JS 指定的范圍。
2. ReferenceError
當(dāng)對(duì)變量或項(xiàng)目的引用被破壞時(shí),將會(huì)引發(fā)此錯(cuò)誤。那是變量或項(xiàng)目不存在。
例如
const l=console.logconst cat = "cat" cat dog
有一個(gè)變量cat被初始化為 “cat”。接下來(lái)引用了cat變量和dog變量。cat變量存在,而dog變量不存在。
cat將返回 “cat”,而dog將引發(fā)引用錯(cuò)誤,因?yàn)樵诃h(huán)境記錄中找不到名稱(chēng)dog。
$ node errors
errors.js:3
dog
^ReferenceError: dog is not defined
每當(dāng)我們創(chuàng)建或定義變量時(shí),變量名稱(chēng)都會(huì)寫(xiě)入環(huán)境記錄中。環(huán)境記錄就像鍵值存儲(chǔ)一樣,
+-------------+
| Key | Value |
---------------
| cat | "cat" |
+-------------+
每當(dāng)我們引用變量時(shí),它都會(huì)存儲(chǔ)程序中定義的變量。當(dāng)在記錄中找到環(huán)境值并提取并返回值時(shí),將以該變量的名稱(chēng)作為關(guān)鍵字在環(huán)境記錄進(jìn)行搜索。調(diào)用尚未定義的函數(shù)。
現(xiàn)在,當(dāng)我們創(chuàng)建或定義一個(gè)沒(méi)有賦值的變量時(shí)。變量將其鍵作為變量名寫(xiě)入環(huán)境記錄,但其值將會(huì)保持未定義的狀態(tài)。
var catenv record
+-----------------+
| Key | Value |
-------------------
| cat | undefined |
+-----------------+
稍后為變量分配值時(shí),將在環(huán)境記錄中搜索該變量,當(dāng)發(fā)現(xiàn)它未定義值時(shí),該賦值將被覆蓋。
var cat
cat = "cat"env record
+-------------+
| Key | Value |
---------------
| cat | "cat" |
+-------------+
所以當(dāng)在環(huán)境記錄中找不到變量名時(shí),JS 引擎將引發(fā) RefernceError。
+-------------+
| Key | Value |
---------------
| cat | "cat" |
+-------------+cat // "cat", yes, :) it's there
dog // :( what's this? can't find it
注意:未定義的變量不會(huì)拋出 ReferenceError,因?yàn)樗谟诃h(huán)境記錄中的值尚未設(shè)置。
3. SyntaxError
這是最常見(jiàn)的錯(cuò)誤。當(dāng)我們輸入 JS 引擎不能理解的代碼時(shí),就會(huì)發(fā)生這個(gè)錯(cuò)誤。
JS 引擎在解析期間捕獲了這個(gè)錯(cuò)誤。在 JS 引擎中,我們的代碼經(jīng)歷了不同的階段,然后才能在終端上看到結(jié)果。
- 標(biāo)記化
- 解析
- 解釋
標(biāo)記化將代碼的源分解為各個(gè)單元。在此階段,將對(duì)數(shù)字、關(guān)鍵字、文字、運(yùn)算符進(jìn)行分類(lèi)并分別標(biāo)記。
接下來(lái),生成的標(biāo)記流將會(huì)傳遞到解析階段,由解析器處理。這是從標(biāo)記流生成 AST 的地方。 AST 是代碼結(jié)構(gòu)的抽象表示。
在標(biāo)記化和解析這兩個(gè)階段,如果我們代碼的語(yǔ)法不符合 JS 的語(yǔ)法規(guī)則,則會(huì)使該階段失敗并引發(fā) SyntaxError。例如:
const l = console.loglet cat h = "cat"
代碼中的 “h” 代表什么?這個(gè) “h” 破壞了代碼。
$ node errors
errors.js:3
let cat h = "cat"
^SyntaxError: Unexpected identifier
看,Node.js 指出了問(wèn)題的所在。它說(shuō) “h” 是意外的,它破壞了cat 變量的聲明。
因此,可以說(shuō)語(yǔ)法錯(cuò)誤在解析或編譯期間發(fā)生。
4. TypeError
當(dāng)其他 NativeError 對(duì)象中沒(méi)有適當(dāng)?shù)氖≡虻闹甘緯r(shí),TypeError 用于指示操作失敗。
對(duì)錯(cuò)誤的數(shù)據(jù)類(lèi)型執(zhí)行操作時(shí)會(huì)發(fā)生 TypeError,例如:
如果我們嘗試將數(shù)字轉(zhuǎn)換為大寫(xiě),如下所示:
const num = 123 num.toUpperCase()
這將引發(fā)TypeError
$ node errors
errors.js:4
num.toUpperCase()
^TypeError: num.toUpperCase is not a function
因?yàn)閠oUpperCase函數(shù)需要字符串?dāng)?shù)據(jù)類(lèi)型。toUpperCase函數(shù)是有意通用的;它不需要其this值是String對(duì)象。因此,可以將其轉(zhuǎn)移到其他種類(lèi)的對(duì)象中用作方法。
只有字符串才會(huì)轉(zhuǎn)換為大寫(xiě)或小寫(xiě)形式,如果我們?cè)?Objects、Boolean、Symbol、null、undefined 數(shù)據(jù)類(lèi)型上調(diào)用toUpperCase函數(shù),則將會(huì)得到 TypeError,因?yàn)樗僮鞯臄?shù)據(jù)類(lèi)型錯(cuò)誤。
5. URIError
這表明使用了一種與其定義不兼容的全局 URI 處理函數(shù)。
JS 中的 URI(統(tǒng)一資源指示符)具有以下功能:decodeURI、decodeURIComponent 等。
如果我們用錯(cuò)誤的參數(shù)去調(diào)用其中任何一個(gè),將得會(huì)到一個(gè) URIError。
decodeURI("%")
^URIError: URI malformed
encodeURI用于獲取 URI 的未編碼版本。 “%” 不是正確的 URI,因此引發(fā)了URIError。
當(dāng) URI 編碼或解碼出現(xiàn)問(wèn)題時(shí),會(huì)引發(fā) URIError。
6. EvalError
當(dāng)使用全局eval()函數(shù)時(shí),這用于識(shí)別錯(cuò)誤。
根據(jù) EcmaSpec 2018 版:
此規(guī)范當(dāng)前未使用此異常。保留它目的是為了與本規(guī)范的先前版本兼容。
7. InternalError
該錯(cuò)誤在 JS 引擎內(nèi)部發(fā)生,特別是當(dāng)它有太多數(shù)據(jù)要處理并且棧增長(zhǎng)超過(guò)其關(guān)鍵限制的時(shí)侯。
當(dāng) JS 引擎被過(guò)多的遞歸和切換情況等淹沒(méi)時(shí),就會(huì)發(fā)生這種問(wèn)題
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
}
以下是一個(gè)簡(jiǎn)單的過(guò)多遞歸的例子:
function foo() {
foo()
}
foo()
總結(jié)
正如我們所說(shuō),誰(shuí)都會(huì)犯錯(cuò)誤。就我們敲代碼這件事而言,這是一個(gè)穩(wěn)定的事件。為了克服它,我們需要知道可以拋出的原生錯(cuò)誤的類(lèi)型。本文中列出了它們,并提供了一些示例來(lái)說(shuō)明它們是如何引發(fā)的。
所以無(wú)論什么時(shí)候在終端或?yàn)g覽器中引發(fā)錯(cuò)誤,你都可以輕松發(fā)現(xiàn)錯(cuò)誤產(chǎn)生的位置和方式,并能夠編寫(xiě)更好、更不易出錯(cuò)的代碼。
以上就是7個(gè)你應(yīng)該知道的JS原生錯(cuò)誤類(lèi)型的詳細(xì)內(nèi)容,更多關(guān)于JS原生錯(cuò)誤類(lèi)型的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序-可移動(dòng)菜單的實(shí)現(xiàn)過(guò)程詳解
這篇文章主要介紹了微信小程序-可移動(dòng)菜單的實(shí)現(xiàn)過(guò)程詳解,我們可以經(jīng)??吹绞謾C(jī)app里有的菜單欄是懸浮在首頁(yè)的,用戶(hù)可以拖動(dòng)和點(diǎn)擊菜單欄進(jìn)行交互,今天就教大家利用小程序的控件,,需要的朋友可以參考下2019-06-06
JS判斷頁(yè)面加載狀態(tài)以及添加遮罩和緩沖動(dòng)畫(huà)的代碼
JS判斷頁(yè)面加載狀態(tài)以及添加遮罩和緩沖動(dòng)畫(huà)的代碼廢話少說(shuō),直接貼代碼!有注釋2012-10-10
Postman無(wú)法正常返回結(jié)果問(wèn)題解決
這篇文章主要介紹了Postman無(wú)法正常返回結(jié)果問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
微信小程序?qū)崙?zhàn)之網(wǎng)易云音樂(lè)歌曲詳情頁(yè)實(shí)現(xiàn)代碼
本文給大家介紹了微信小程序?qū)W習(xí)記錄之網(wǎng)易云音樂(lè)歌曲詳情頁(yè)代碼實(shí)現(xiàn),代碼分為html、css和js部分,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05
TypeScript在Vuex4中使用TS實(shí)戰(zhàn)分享
這篇文章主要介紹了TypeScript在Vuex4中使用TS實(shí)戰(zhàn)分享,vuex4類(lèi)型?Api分析和vuex4實(shí)戰(zhàn)兩部分講述,需要的小伙伴可以參考一下2022-06-06
原生JavaScript中直接觸發(fā)事件的方式小結(jié)
JavaScript提供了多種方式來(lái)直接觸發(fā)事件,無(wú)論是在用戶(hù)交互、程序邏輯處理或是數(shù)據(jù)更新時(shí),本文將全面探討原生JavaScript中各種事件觸發(fā)方式,并通過(guò)深入的技術(shù)案例分析,需要的朋友可以參考下2025-01-01
對(duì)象題目的一個(gè)坑 理解Javascript對(duì)象
這篇文章主要介紹了Javascript對(duì)象,特別為大家分享了對(duì)象題目的一個(gè)坑,提供了解題思路,感興趣的小伙伴們可以參考一下2015-12-12

