日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
處理JavaScript錯(cuò)誤的權(quán)威指南

墨菲定律指出,任何可能出錯(cuò)的事情最終都會(huì)出錯(cuò)。這在編程世界中應(yīng)用得太好了。如果您創(chuàng)建一個(gè)應(yīng)用程序,您很可能會(huì)產(chǎn)生錯(cuò)誤和其他問(wèn)題。JavaScript中的錯(cuò)誤就是這樣一個(gè)常見(jiàn)問(wèn)題!

讓客戶(hù)滿意是我們工作的目標(biāo),不斷超越客戶(hù)的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶(hù),將通過(guò)不懈努力成為客戶(hù)在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名申請(qǐng)、網(wǎng)頁(yè)空間、營(yíng)銷(xiāo)軟件、網(wǎng)站建設(shè)、市北網(wǎng)站維護(hù)、網(wǎng)站推廣。

軟件產(chǎn)品的成功取決于其創(chuàng)建者在傷害用戶(hù)之前解決這些問(wèn)題的能力。在所有編程語(yǔ)言中, JavaScript因其平均錯(cuò)誤處理設(shè)計(jì)而臭名昭著。

如果您正在構(gòu)建一個(gè)JavaScript應(yīng)用程序,那么您很有可能會(huì)在某一時(shí)刻弄亂數(shù)據(jù)類(lèi)型。如果不是這樣,那么您最終可能會(huì)將undefined替換為null或?qū)⑷忍?hào)運(yùn)算符 ( ===) 替換為雙等號(hào)運(yùn)算符 ( ==)。

犯錯(cuò)是人之常情。這就是為什么我們將向您展示您需要了解的有關(guān)處理JavaScript錯(cuò)誤的所有信息。

本文將引導(dǎo)您了解JavaScript中的基本錯(cuò)誤,并解釋您可能遇到的各種錯(cuò)誤。然后,您將學(xué)習(xí)如何識(shí)別和修復(fù)這些錯(cuò)誤。還有一些技巧可以在生產(chǎn)環(huán)境中有效地處理錯(cuò)誤。

什么是JavaScript錯(cuò)誤?

編程錯(cuò)誤是指程序無(wú)法正常運(yùn)行的情況。當(dāng)程序不知道如何處理手頭的工作時(shí),可能會(huì)發(fā)生這種情況,例如嘗試打開(kāi)不存在的文件或在沒(méi)有網(wǎng)絡(luò)連接的情況下訪問(wèn)基于Web的API端點(diǎn)時(shí)。

這些情況促使程序向用戶(hù)拋出錯(cuò)誤,說(shuō)明它不知道如何繼續(xù)。該程序收集盡可能多的有關(guān)錯(cuò)誤的信息,然后報(bào)告它無(wú)法繼續(xù)前進(jìn)。

聰明的程序員試圖預(yù)測(cè)和覆蓋這些場(chǎng)景,這樣用戶(hù)就不必獨(dú)立地找出像“404”這樣的技術(shù)錯(cuò)誤信息。相反,它們顯示了一條更容易理解的信息:“找不到該頁(yè)面?!?/p>

JavaScript中的錯(cuò)誤是在發(fā)生編程錯(cuò)誤時(shí)顯示的對(duì)象。這些對(duì)象包含有關(guān)錯(cuò)誤類(lèi)型、導(dǎo)致錯(cuò)誤的語(yǔ)句以及發(fā)生錯(cuò)誤時(shí)的堆棧跟蹤的大量信息。JavaScript還允許程序員創(chuàng)建自定義錯(cuò)誤,以便在調(diào)試問(wèn)題時(shí)提供額外信息。

錯(cuò)誤的屬性

現(xiàn)在JavaScript錯(cuò)誤的定義已經(jīng)很清楚了,是時(shí)候深入研究細(xì)節(jié)了。

JavaScript中的錯(cuò)誤帶有某些標(biāo)準(zhǔn)和自定義屬性,有助于理解錯(cuò)誤的原因和影響。默認(rèn)情況下,JavaScript中的錯(cuò)誤包含三個(gè)屬性:

此外,error還可以攜帶columnNumber、lineNumber、fileName等屬性,以更好地描述錯(cuò)誤。但是,這些屬性不是標(biāo)準(zhǔn)的,可能會(huì)出現(xiàn)在JavaScript應(yīng)用程序生成的每個(gè)錯(cuò)誤對(duì)象中,也可能不會(huì)出現(xiàn)。

了解堆棧跟蹤

堆棧跟蹤是發(fā)生異常或警告等事件時(shí)程序所在的方法調(diào)用列表。這是伴隨異常的示例堆棧跟蹤的樣子:

堆棧跟蹤示例

如您所見(jiàn),它首先打印錯(cuò)誤名稱(chēng)和消息,然后是被調(diào)用的方法列表。每個(gè)方法調(diào)用都說(shuō)明其源代碼的位置以及調(diào)用它的行。您可以使用這些數(shù)據(jù)瀏覽您的代碼庫(kù)并確定是哪段代碼導(dǎo)致了錯(cuò)誤。

此方法列表以堆疊方式排列。它顯示了您的異常首次引發(fā)的位置以及它如何通過(guò)堆疊的方法調(diào)用傳播。為異常實(shí)現(xiàn)捕獲不會(huì)讓它通過(guò)堆棧向上傳播并使您的程序崩潰。但是,您可能希望在某些情況下故意不捕獲致命錯(cuò)誤以使程序崩潰。

錯(cuò)誤與異常

大多數(shù)人通常將錯(cuò)誤和異常視為同一件事。但是,必須注意它們之間的細(xì)微但根本的區(qū)別。

異常是已拋出的錯(cuò)誤對(duì)象。

為了更好地理解這一點(diǎn),讓我們舉一個(gè)簡(jiǎn)單的例子。以下是如何在JavaScript中定義錯(cuò)誤:

const wrongTypeError = TypeError("Wrong type found, expected character")

這就是wrongTypeError對(duì)象變成異常的方式:

throw wrongTypeError

然而,大多數(shù)人傾向于使用在拋出錯(cuò)誤對(duì)象時(shí)定義錯(cuò)誤對(duì)象的簡(jiǎn)寫(xiě)形式:

throw TypeError("Wrong type found, expected character")

這是標(biāo)準(zhǔn)做法。然而,這也是開(kāi)發(fā)人員傾向于混淆異常和錯(cuò)誤的原因之一。因此,即使您使用速記來(lái)快速完成工作,了解基礎(chǔ)知識(shí)也至關(guān)重要。

JavaScript中的錯(cuò)誤類(lèi)型

JavaScript中有一系列預(yù)定義的錯(cuò)誤類(lèi)型。只要程序員沒(méi)有明確處理應(yīng)用程序中的錯(cuò)誤,它們就會(huì)由 JavaScript 運(yùn)行時(shí)自動(dòng)選擇和定義。

本節(jié)將引導(dǎo)您了解JavaScript中一些最常見(jiàn)的錯(cuò)誤類(lèi)型,并了解它們發(fā)生的時(shí)間和原因。

范圍錯(cuò)誤

當(dāng)變量設(shè)置為超出其合法值范圍時(shí),會(huì)引發(fā)RangeError。它通常發(fā)生在將值作為參數(shù)傳遞給函數(shù)時(shí),并且給定值不在函數(shù)參數(shù)的范圍內(nèi)。使用文檔記錄不佳的第三方庫(kù)時(shí),有時(shí)修復(fù)起來(lái)會(huì)很棘手,因?yàn)槟枰绤?shù)的可能值范圍才能傳遞正確的值。

RangeError發(fā)生的一些常見(jiàn)場(chǎng)景是:

  • 試圖通過(guò)Array構(gòu)造函數(shù)創(chuàng)建一個(gè)非法長(zhǎng)度的數(shù)組。
  • 將錯(cuò)誤值傳遞給數(shù)字方法,如toExponential()toPrecision(),toFixed()等。
  • 將非法值傳遞給字符串函數(shù),例如normalize().

參考錯(cuò)誤

當(dāng)您的代碼中的變量引用出現(xiàn)問(wèn)題時(shí),就會(huì)發(fā)生ReferenceError。您可能忘記在使用變量之前為其定義值,或者您可能試圖在代碼中使用不可訪問(wèn)的變量。在任何情況下,通過(guò)堆棧跟蹤提供了充足的信息來(lái)查找和修復(fù)有錯(cuò)誤的變量引用。

ReferenceErrors發(fā)生的一些常見(jiàn)原因是:

  • 在變量名中打錯(cuò)字。
  • 試圖訪問(wèn)其范圍之外的塊范圍變量。
  • 在加載之前從外部庫(kù)引用全局變量(例如 $ from jQuery)。

語(yǔ)法錯(cuò)誤

這些錯(cuò)誤是最容易修復(fù)的錯(cuò)誤之一,因?yàn)樗鼈儽砻鞔a語(yǔ)法有錯(cuò)誤。由于JavaScript是一種解釋而不是編譯的腳本語(yǔ)言,因此當(dāng)應(yīng)用程序執(zhí)行包含錯(cuò)誤的腳本時(shí)會(huì)拋出這些腳本語(yǔ)言。在編譯語(yǔ)言的情況下,在編譯過(guò)程中會(huì)識(shí)別出此類(lèi)錯(cuò)誤。因此,在修復(fù)之前不會(huì)創(chuàng)建應(yīng)用程序二進(jìn)制文件。

可能發(fā)生SyntaxErrors的一些常見(jiàn)原因是:

  • 缺少引號(hào)
  • 缺少右括號(hào)
  • 花括號(hào)或其他字符的不正確對(duì)齊

最好在IDE中使用linting工具在此類(lèi)錯(cuò)誤出現(xiàn)在瀏覽器之前為您識(shí)別這些錯(cuò)誤。

類(lèi)型錯(cuò)誤

TypeError是JavaScript應(yīng)用程序中最常見(jiàn)的錯(cuò)誤之一。當(dāng)某些值不是特定的預(yù)期類(lèi)型時(shí),會(huì)創(chuàng)建此錯(cuò)誤。發(fā)生時(shí)的一些常見(jiàn)情況是:

  • 調(diào)用不是方法的對(duì)象。
  • 試圖訪問(wèn)空對(duì)象或未定義對(duì)象的屬性
  • 將字符串視為數(shù)字,反之亦然

發(fā)生TypeError的可能性還有很多。稍后我們將查看一些著名的實(shí)例并學(xué)習(xí)如何修復(fù)它們。

內(nèi)部錯(cuò)誤

當(dāng)JavaScript運(yùn)行時(shí)引擎中發(fā)生異常時(shí)使用InternalError類(lèi)型。它可能表示也可能不表示您的代碼存在問(wèn)題。

通常,InternalError僅在兩種情況下發(fā)生:

  • 當(dāng)JavaScript運(yùn)行時(shí)的補(bǔ)丁或更新帶有引發(fā)異常的錯(cuò)誤時(shí)(這種情況很少發(fā)生)
  • 當(dāng)你的代碼包含對(duì)JavaScript引擎來(lái)說(shuō)太大的實(shí)體時(shí)(例如太多的switch case、太大的數(shù)組初始化器、太多的遞歸)

解決此錯(cuò)誤的最合適方法是通過(guò)錯(cuò)誤消息確定原因,并在可能的情況下重構(gòu)您的應(yīng)用程序邏輯,以消除JavaScript引擎上的工作負(fù)載突然激增。

URI錯(cuò)誤

URIError發(fā)生在全局URI處理函數(shù)如decodeURIComponent被非法使用時(shí)。它通常表示傳遞給方法調(diào)用的參數(shù)不符合URI標(biāo)準(zhǔn),因此沒(méi)有被方法正確解析。

診斷這些錯(cuò)誤通常很容易,因?yàn)槟恍枰獧z查參數(shù)是否存在畸形。

評(píng)估錯(cuò)誤

當(dāng)函數(shù)eval()調(diào)用發(fā)生錯(cuò)誤時(shí)會(huì)發(fā)生EvalError 。eval()函數(shù)用于執(zhí)行存儲(chǔ)在字符串中的 JavaScript 代碼。但是,由于安全問(wèn)題,強(qiáng)烈建議不要使用eval()函數(shù),并且當(dāng)前的ECMAScript規(guī)范不再拋出EvalError類(lèi),因此存在此錯(cuò)誤類(lèi)型只是為了保持與舊版JavaScript代碼的向后兼容性。

如果您使用的是舊版本的JavaScript,則可能會(huì)遇到此錯(cuò)誤。無(wú)論如何,最好調(diào)查eval()函數(shù)調(diào)用中執(zhí)行的代碼是否有任何異常。

創(chuàng)建自定義錯(cuò)誤類(lèi)型

雖然JavaScript提供了足夠的錯(cuò)誤類(lèi)型列表來(lái)涵蓋大多數(shù)場(chǎng)景,但如果列表不滿足您的要求,您始終可以創(chuàng)建新的錯(cuò)誤類(lèi)型。這種靈活性的基礎(chǔ)在于JavaScript允許您使用throw命令逐字地拋出任何東西。

因此,從技術(shù)上講,這些聲明是完全合法的:

throw 8
throw "An error occurred"

但是,拋出原始數(shù)據(jù)類(lèi)型不會(huì)提供有關(guān)錯(cuò)誤的詳細(xì)信息,例如其類(lèi)型、名稱(chēng)或隨附的堆棧跟蹤。為了解決這個(gè)問(wèn)題并標(biāo)準(zhǔn)化錯(cuò)誤處理過(guò)程,我們提供了Error這個(gè)類(lèi)。也不鼓勵(lì)在拋出異常時(shí)使用原始數(shù)據(jù)類(lèi)型。

您可以擴(kuò)展Error類(lèi)以創(chuàng)建您的自定義錯(cuò)誤類(lèi)。以下是如何執(zhí)行此操作的基本示例:

class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}

您可以通過(guò)以下方式使用它:

throw ValidationError("Property not found: name")

然后您可以使用instanceof關(guān)鍵字識(shí)別它:

try {
validateForm() // code that throws a ValidationError
} catch (e) {
if (e instanceof ValidationError)
// do something
else
// do something else
}

JavaScript中最常見(jiàn)的10個(gè)錯(cuò)誤

現(xiàn)在您已經(jīng)了解了常見(jiàn)的錯(cuò)誤類(lèi)型以及如何創(chuàng)建自定義錯(cuò)誤類(lèi)型,是時(shí)候看看您在編寫(xiě)JavaScript代碼時(shí)會(huì)遇到的一些最常見(jiàn)的錯(cuò)誤了。

1. Uncaught RangeError

在幾種不同的情況下,Google Chrome中會(huì)出現(xiàn)此錯(cuò)誤。首先,如果您調(diào)用遞歸函數(shù)并且它不會(huì)終止,則可能會(huì)發(fā)生這種情況。您可以在Chrome開(kāi)發(fā)者控制臺(tái)中自行查看:

帶有遞歸函數(shù)調(diào)用的RangeError示例

因此,要解決此類(lèi)錯(cuò)誤,請(qǐng)確保正確定義遞歸函數(shù)的邊界情況。發(fā)生此錯(cuò)誤的另一個(gè)原因是您傳遞的值超出了函數(shù)的參數(shù)范圍。這是一個(gè)例子:

帶有toExponential()調(diào)用的RangeError示例

錯(cuò)誤消息通常會(huì)指出您的代碼有什么問(wèn)題。一旦你做出改變,它就會(huì)得到解決。

toExponential() 函數(shù)調(diào)用的輸出

2. Uncaught TypeError: Cannot set property

當(dāng)您在未定義的引用上設(shè)置屬性時(shí)會(huì)發(fā)生此錯(cuò)誤。您可以使用此代碼重現(xiàn)該問(wèn)題:

var list
list.count = 0

這是您將收到的輸出:

類(lèi)型錯(cuò)誤示例

要修復(fù)此錯(cuò)誤,請(qǐng)?jiān)谠L問(wèn)其屬性之前使用值初始化引用。以下是修復(fù)后的外觀:

如何修復(fù)類(lèi)型錯(cuò)誤

3. Uncaught TypeError: Cannot read property

這是JavaScript中最常出現(xiàn)的錯(cuò)誤之一。當(dāng)您嘗試讀取屬性或調(diào)用未定義對(duì)象的函數(shù)時(shí),會(huì)發(fā)生此錯(cuò)誤。您可以通過(guò)在Chrome開(kāi)發(fā)人員控制臺(tái)中運(yùn)行以下代碼來(lái)非常輕松地重現(xiàn)它:

var func
func.call()

這是輸出:

帶有未定義函數(shù)的TypeError示例

未定義的對(duì)象是導(dǎo)致此錯(cuò)誤的眾多可能原因之一。此問(wèn)題的另一個(gè)突出原因可能是在呈現(xiàn) UI 時(shí)未正確初始化狀態(tài)。這是來(lái)自React應(yīng)用程序的真實(shí)示例:

import React, { useState, useEffect } from "react";
const CardsList = () => {
const [state, setState] = useState();
useEffect(() => {
setTimeout(() => setState({ items: ["Card 1", "Card 2"] }), 2000);
}, []);
return (
<>
{state.items.map((item) => (
  • {item}
  • ))} ); }; export default CardsList;

    該應(yīng)用程序從一個(gè)空狀態(tài)容器開(kāi)始,并在延遲2秒后提供一些項(xiàng)目。延遲用于模擬網(wǎng)絡(luò)調(diào)用。即使您的網(wǎng)絡(luò)速度非常快,您仍然會(huì)面臨輕微的延遲,因?yàn)樵摻M件將至少呈現(xiàn)一次。如果您嘗試運(yùn)行此應(yīng)用程序,您將收到以下錯(cuò)誤:

    瀏覽器中的TypeError堆棧跟蹤

    這是因?yàn)?,在渲染時(shí),狀態(tài)容器是未定義的;因此,它不存在任何財(cái)產(chǎn)items。修復(fù)這個(gè)錯(cuò)誤很容易。您只需要為狀態(tài)容器提供初始默認(rèn)值。

    // ...
    const [state, setState] = useState({items: []});
    // ...

    現(xiàn)在,在設(shè)置延遲之后,您的應(yīng)用程序?qū)@示類(lèi)似的輸出:

    代碼輸出

    代碼中的確切修復(fù)可能會(huì)有所不同,但這里的本質(zhì)是始終在使用變量之前正確初始化它們。

    4. TypeError: ‘undefined’ is not an object

    當(dāng)您嘗試訪問(wèn)未定義對(duì)象的屬性或調(diào)用未定義對(duì)象的方法時(shí),會(huì)在Safari中發(fā)生此錯(cuò)誤。您可以從上面運(yùn)行相同的代碼來(lái)自己重現(xiàn)錯(cuò)誤。

    帶有未定義函數(shù)的TypeError示例

    這個(gè)錯(cuò)誤的解決方法也是一樣的——確保你已經(jīng)正確地初始化了你的變量,并且在訪問(wèn)一個(gè)屬性或方法時(shí)它們不是未定義的。

    5. TypeError: null is not an object

    這又與前面的錯(cuò)誤相似。它發(fā)生在Safari上,這兩個(gè)錯(cuò)誤之間的唯一區(qū)別是,當(dāng)正在訪問(wèn)其屬性或方法的對(duì)象null不是undefined. 您可以通過(guò)運(yùn)行以下代碼來(lái)重現(xiàn)這一點(diǎn):

    var func = null
    func.call()

    這是您將收到的輸出:

    帶有null函數(shù)的TypeError示例

    因?yàn)?code>null是顯式設(shè)置為變量的值,而不是由JavaScript自動(dòng)分配的值。僅當(dāng)您嘗試訪問(wèn)null自己設(shè)置的變量時(shí),才會(huì)發(fā)生此錯(cuò)誤。因此,您需要重新訪問(wèn)您的代碼并檢查您編寫(xiě)的邏輯是否正確。

    6. TypeError: Cannot read property ‘length’

    當(dāng)您嘗試讀取nullundefined對(duì)象的長(zhǎng)度時(shí),Chrome中會(huì)出現(xiàn)此錯(cuò)誤。這個(gè)問(wèn)題的原因和前面的問(wèn)題類(lèi)似,但是在處理列表的時(shí)候出現(xiàn)的頻率比較高;因此值得特別提及。以下是重現(xiàn)問(wèn)題的方法:

    帶有未定義對(duì)象的TypeError示例

    但是,在較新版本的Chrome中,此錯(cuò)誤報(bào)告為Uncaught TypeError: Cannot read properties of undefined. 這是它現(xiàn)在的樣子:

    在較新的Chrome版本上帶有未定義對(duì)象的TypeError示例

    再次,修復(fù)是確保您嘗試訪問(wèn)其長(zhǎng)度的對(duì)象存在并且未設(shè)置為null.

    7. TypeError: ‘undefined’ is not a function

    當(dāng)您嘗試調(diào)用腳本中不存在的方法或該方法存在但無(wú)法在調(diào)用上下文中引用時(shí),會(huì)發(fā)生此錯(cuò)誤。這個(gè)錯(cuò)誤通常發(fā)生在谷歌瀏覽器中,您可以通過(guò)檢查拋出錯(cuò)誤的代碼行來(lái)解決它。如果您發(fā)現(xiàn)拼寫(xiě)錯(cuò)誤,請(qǐng)修復(fù)它并檢查它是否能解決您的問(wèn)題。

    如果您在代碼中使用了自引用關(guān)鍵字this,如果this沒(méi)有適當(dāng)?shù)亟壎ǖ侥纳舷挛?,則可能會(huì)出現(xiàn)此錯(cuò)誤??紤]下面的代碼:

    function showAlert() {
    alert("message here")
    }
    document.addEventListener("click", () => {
    this.showAlert();
    })

    如果執(zhí)行上述代碼,它將拋出我們討論過(guò)的錯(cuò)誤。之所以會(huì)發(fā)生這種情況,是因?yàn)樽鳛槭录陕?tīng)器傳遞的匿名函數(shù)正在document的上下文中執(zhí)行。

    相比之下,showAlert函數(shù)是在window的上下文中定義的。

    為了解決這個(gè)問(wèn)題,您必須通過(guò)將函數(shù)與bind()方法綁定來(lái)傳遞對(duì)函數(shù)的正確引用:

    document.addEventListener("click", this.showAlert.bind(this))

    8. ReferenceError: event is not defined

    當(dāng)您嘗試訪問(wèn)未在調(diào)用范圍內(nèi)定義的引用時(shí),會(huì)發(fā)生此錯(cuò)誤。這通常發(fā)生在處理事件時(shí),因?yàn)樗鼈兘?jīng)常為您提供event回調(diào)函數(shù)中調(diào)用的引用。如果您忘記在函數(shù)的參數(shù)中定義事件參數(shù)或拼寫(xiě)錯(cuò)誤,則可能會(huì)發(fā)生此錯(cuò)誤。

    在Internet Explorer或Google Chrome中可能不會(huì)發(fā)生此錯(cuò)誤(因?yàn)镮E提供了一個(gè)全局事件變量,并且Chrome會(huì)自動(dòng)將事件變量附加到處理程序),但它可能在Firefox中發(fā)生。所以建議留意這樣的小錯(cuò)誤。

    9. TypeError: Assignment to constant variable

    這是由于粗心造成的錯(cuò)誤。如果您嘗試將新值分配給常量變量,您將遇到這樣的結(jié)果:

    帶有常量對(duì)象分配的TypeError示例

    雖然現(xiàn)在看起來(lái)很容易修復(fù),但想象一下數(shù)百個(gè)這樣的變量聲明,其中一個(gè)被錯(cuò)誤地定義為const而不是let! 與PHP等其他腳本語(yǔ)言不同,在JavaScript中聲明常量和變量的風(fēng)格差別很小。因此,當(dāng)您遇到此錯(cuò)誤時(shí),建議首先檢查您的聲明。如果您忘記上述引用是一個(gè)常量并將其用作變量,您也可能會(huì)遇到此錯(cuò)誤。這表明您的應(yīng)用程序邏輯存在粗心或缺陷。嘗試解決此問(wèn)題時(shí),請(qǐng)務(wù)必檢查此項(xiàng)。

    10.(unknown): Script error

    當(dāng)?shù)谌侥_本向您的瀏覽器發(fā)送錯(cuò)誤時(shí),就會(huì)發(fā)生腳本錯(cuò)誤。此錯(cuò)誤后跟(未知),因?yàn)?/i>第三方腳本與您的應(yīng)用屬于不同的域。瀏覽器隱藏了其他細(xì)節(jié),以防止第三方腳本泄露敏感信息。

    在不了解完整詳細(xì)信息的情況下,您無(wú)法解決此錯(cuò)誤。您可以執(zhí)行以下操作來(lái)獲取有關(guān)該錯(cuò)誤的更多信息:

    一旦您可以訪問(wèn)錯(cuò)誤的詳細(xì)信息,您就可以著手解決問(wèn)題,這可能與第三方庫(kù)或網(wǎng)絡(luò)有關(guān)。

    如何識(shí)別和防止JavaScript中的錯(cuò)誤

    雖然上面討論的錯(cuò)誤是JavaScript中最常見(jiàn)和最常見(jiàn)的錯(cuò)誤,但您會(huì)遇到,僅僅依靠幾個(gè)示例是遠(yuǎn)遠(yuǎn)不夠的。在開(kāi)發(fā)JavaScript應(yīng)用程序時(shí),了解如何檢測(cè)和防止任何類(lèi)型的錯(cuò)誤至關(guān)重要。以下是如何處理JavaScript中的錯(cuò)誤。

    手動(dòng)拋出和捕獲錯(cuò)誤

    處理手動(dòng)或運(yùn)行時(shí)拋出的錯(cuò)誤的最基本方法是捕獲它們。與大多數(shù)其他語(yǔ)言一樣,JavaScript提供了一組關(guān)鍵字來(lái)處理錯(cuò)誤。在著手處理JavaScript應(yīng)用程序中的錯(cuò)誤之前,必須深入了解它們中的每一個(gè)。

    throw

    該集合的第一個(gè)也是最基本的關(guān)鍵字是throw. 很明顯,throw關(guān)鍵字用于拋出錯(cuò)誤以在JavaScript運(yùn)行時(shí)手動(dòng)創(chuàng)建異常。我們已經(jīng)在本文前面討論過(guò)這個(gè)問(wèn)題,這里是這個(gè)關(guān)鍵字意義的要點(diǎn):

    • 你可以throw做任何事情,包括數(shù)字、字符串和Error對(duì)象。
    • 但是,不建議拋出諸如字符串和數(shù)字之類(lèi)的原始數(shù)據(jù)類(lèi)型,因?yàn)樗鼈儾粩y帶有關(guān)錯(cuò)誤的調(diào)試信息。
    • 例子:throw TypeError("Please provide a string")

    try

    try關(guān)鍵字用于指示代碼塊可能會(huì)引發(fā)異常。它的語(yǔ)法是:

    try {
    // error-prone code here
    }

    重要的是要注意,catch塊必須始終跟隨try塊才能有效地處理錯(cuò)誤。

    catch

    catch關(guān)鍵字用于創(chuàng)建一個(gè)catch塊。此代碼塊負(fù)責(zé)處理尾隨try塊捕獲的錯(cuò)誤。這是它的語(yǔ)法:

    catch (exception) {
    // code to handle the exception here
    }

    這就是你如何一起實(shí)現(xiàn)trycatch塊的方式:

    try {
    // business logic code
    } catch (exception) {
    // error handling code
    }

    與C++或Java不同,您不能將多個(gè)catch塊附加到JavaScript中的try塊。這意味著您不能這樣做:

    try {
    // business logic code
    } catch (exception) {
    if (exception instanceof TypeError) {
    // do something
    }
    } catch (exception) {
    if (exception instanceof RangeError) {
    // do something
    }
    }

    相反,您可以在單個(gè)catch塊中使用if...else語(yǔ)句或switch case語(yǔ)句來(lái)處理所有可能的錯(cuò)誤情況。它看起來(lái)像這樣:

    try {
    // business logic code
    } catch (exception) {
    if (exception instanceof TypeError) {
    // do something
    } else if (exception instanceof RangeError) {
    // do something else
    }
    }

    finally

    finally關(guān)鍵字用于定義在處理錯(cuò)誤后運(yùn)行的代碼塊。該塊在try和catch塊之后執(zhí)行。

    此外,無(wú)論其他兩個(gè)塊的結(jié)果如何,都會(huì)執(zhí)行finally塊。這意味著即使catch塊不能完全處理錯(cuò)誤或者catch塊中拋出錯(cuò)誤,解釋器也會(huì)在程序崩潰之前執(zhí)行finally塊中的代碼。

    要被認(rèn)為是有效的,JavaScript中的try塊需要后跟catch或finally塊。如果沒(méi)有這些,解釋器將引發(fā)SyntaxError。因此,在處理錯(cuò)誤時(shí),請(qǐng)確保至少遵循您的try塊。

    使用onerror()方法全局處理錯(cuò)誤

    onerror()方法適用于所有HTML元素,用于處理它們可能發(fā)生的任何錯(cuò)誤。例如,如果img標(biāo)簽找不到指定URL的圖像,它會(huì)觸發(fā)其onerror方法以允許用戶(hù)處理錯(cuò)誤。

    通常,您會(huì)在onerror調(diào)用中提供另一個(gè)圖像URL,以便img標(biāo)記回退到。這是您可以通過(guò)JavaScript執(zhí)行此操作的方法:

    const image = document.querySelector("img")
    image.onerror = (event) => {
    console.log("Error occurred: " + event)
    }

    但是,您可以使用此功能為您的應(yīng)用創(chuàng)建全局錯(cuò)誤處理機(jī)制。以下是您的操作方法:

    window.onerror = (event) => {
    console.log("Error occurred: " + event)
    }

    使用此事件處理程序,您可以擺脫try...catch代碼中的多個(gè)塊,并集中您的應(yīng)用程序的錯(cuò)誤處理,類(lèi)似于事件處理。您可以將多個(gè)錯(cuò)誤處理程序附加到窗口,以維護(hù)SOLID設(shè)計(jì)原則中的單一責(zé)任原則。解釋器將循環(huán)遍歷所有處理程序,直到到達(dá)適當(dāng)?shù)奶幚沓绦颉?/p>

    通過(guò)回調(diào)傳遞錯(cuò)誤

    雖然簡(jiǎn)單和線性函數(shù)允許錯(cuò)誤處理保持簡(jiǎn)單,但回調(diào)會(huì)使事情復(fù)雜化。

    考慮以下代碼:

    const calculateCube = (number, callback) => {
    setTimeout(() => {
    const cube = number * number * number
    callback(cube)
    }, 1000)
    }
    const callback = result => console.log(result)
    calculateCube(4, callback)

    上面的函數(shù)演示了一個(gè)異步條件,其中一個(gè)函數(shù)需要一些時(shí)間來(lái)處理操作并稍后在回調(diào)的幫助下返回結(jié)果。

    如果您嘗試在函數(shù)調(diào)用中輸入字符串而不是4,您將得到NaN結(jié)果。

    這需要妥善處理。就是這樣:

    const calculateCube = (number, callback) => {
    setTimeout(() => {
    if (typeof number !== "number")
    throw new Error("Numeric argument is expected")
    const cube = number * number * number
    callback(cube)
    }, 1000)
    }
    const callback = result => console.log(result)
    try {
    calculateCube(4, callback)
    } catch (e) { console.log(e) }

    這應(yīng)該可以理想地解決問(wèn)題。但是,如果您嘗試將字符串傳遞給函數(shù)調(diào)用,您將收到以下信息:

    錯(cuò)誤參數(shù)的錯(cuò)誤示例

    即使您在調(diào)用函數(shù)時(shí)實(shí)現(xiàn)了try-catch塊,它仍然表示錯(cuò)誤未捕獲。由于超時(shí)延遲,在執(zhí)行catch塊后拋出錯(cuò)誤。

    這可能在網(wǎng)絡(luò)調(diào)用中很快發(fā)生,在這種情況下會(huì)出現(xiàn)意外延遲。您需要在開(kāi)發(fā)應(yīng)用程序時(shí)涵蓋此類(lèi)情況。

    以下是在回調(diào)中正確處理錯(cuò)誤的方法:

    const calculateCube = (number, callback) => {
    setTimeout(() => {
    if (typeof number !== "number") {
    callback(new TypeError("Numeric argument is expected"))
    return
    }
    const cube = number * number * number
    callback(null, cube)
    }, 2000)
    }
    const callback = (error, result) => {
    if (error !== null) {
    console.log(error)
    return
    }
    console.log(result)
    }
    try {
    calculateCube('hey', callback)
    } catch (e) {
    console.log(e)
    }

    現(xiàn)在,控制臺(tái)的輸出將是:

    帶有非法參數(shù)的TypeError示例

    這表明錯(cuò)誤已得到適當(dāng)處理。

    處理Promise中的錯(cuò)誤

    大多數(shù)人傾向于使用Promise來(lái)處理異步活動(dòng)。Promise還有另一個(gè)優(yōu)點(diǎn)——被拒絕的Promise不會(huì)終止你的腳本。但是,您仍然需要實(shí)現(xiàn)一個(gè)catch塊來(lái)處理Promise中的錯(cuò)誤。為了更好地理解這一點(diǎn),讓我們使用Promises重寫(xiě)calculateCube()函數(shù):

    const delay = ms => new Promise(res => setTimeout(res, ms));
    const calculateCube = async (number) => {
    if (typeof number !== "number")
    throw Error("Numeric argument is expected")
    await delay(5000)
    const cube = number * number * number
    return cube
    }
    try {
    calculateCube(4).then(r => console.log(r))
    } catch (e) { console.log(e) }

    前面代碼中的超時(shí)已被隔離到delay函數(shù)中以便理解。如果您嘗試輸入一個(gè)字符串而不是4,您獲得的輸出將類(lèi)似于以下內(nèi)容:

    在Promise中帶有非法參數(shù)的TypeError示例

    同樣,這是由于Promise在其他所有內(nèi)容完成執(zhí)行后引發(fā)錯(cuò)誤。這個(gè)問(wèn)題的解決方案很簡(jiǎn)單。只需像這樣向Promise鏈添加調(diào)用catch()

    calculateCube("hey")
    .then(r => console.log(r))
    .catch(e => console.log(e))

    現(xiàn)在輸出將是:

    處理帶有非法參數(shù)的TypeError示例

    您可以觀察到使用Promise處理錯(cuò)誤是多么容易。此外,您可以鏈接finally()塊和promise調(diào)用以添加將在錯(cuò)誤處理完成后運(yùn)行的代碼。

    或者,您也可以使用傳統(tǒng)的try-catch-finally技術(shù)來(lái)處理Promise中的錯(cuò)誤。在這種情況下,您的promise調(diào)用如下所示:

    try {
    let result = await calculateCube("hey")
    console.log(result)
    } catch (e) {
    console.log(e)
    } finally {
    console.log('Finally executed")
    }

    但是,這僅適用于異步函數(shù)。因此,在Promise中處理錯(cuò)誤的最優(yōu)選方式是鏈?zhǔn)竭B接catchfinally連接到Promise調(diào)用。

    throw/catch vs onerror() vs Callbacks vs Promises:哪種方法更佳?

    有四種方法可供您使用,您必須知道如何在任何給定的用例中選擇最合適的方法。以下是您可以自己決定的方法:

    throw/catch

    您將在大多數(shù)情況下使用此方法。確保在你的catch塊中為所有可能的錯(cuò)誤實(shí)現(xiàn)條件,如果你需要在try塊之后運(yùn)行一些內(nèi)存清理例程,請(qǐng)記住包含一個(gè)finally塊。

    但是,太多的try/catch塊會(huì)使您的代碼難以維護(hù)。如果您發(fā)現(xiàn)自己處于這種情況,您可能希望通過(guò)全局處理程序或promise方法來(lái)處理錯(cuò)誤。

    在異步try/catch塊和promise的catch()之間做出決定時(shí),建議使用異步try/catch塊,因?yàn)樗鼈儗⑹鼓拇a線性且易于調(diào)試。

    onerror()

    當(dāng)您知道您的應(yīng)用程序必須處理許多錯(cuò)誤并且它們可以很好地分散在整個(gè)代碼庫(kù)中時(shí),最好使用onerror()方法。onerror方法使您能夠處理錯(cuò)誤,就好像它們只是您的應(yīng)用程序處理的另一個(gè)事件一樣。您可以定義多個(gè)錯(cuò)誤處理程序并在初始呈現(xiàn)時(shí)將它們附加到應(yīng)用程序的窗口。

    但是,您還必須記住,在錯(cuò)誤范圍較小的較小項(xiàng)目中設(shè)置onerror()方法可能會(huì)帶來(lái)不必要的挑戰(zhàn)。如果您確定您的應(yīng)用程序不會(huì)拋出太多錯(cuò)誤,那么傳統(tǒng)的throw/catch方法將最適合您。

    Callbacks and Promises

    回調(diào)和承諾中的錯(cuò)誤處理因代碼設(shè)計(jì)和結(jié)構(gòu)而異。但是,如果您在編寫(xiě)代碼之前在這兩者之間進(jìn)行選擇,最好使用Promise。

    這是因?yàn)镻romise具有用于鏈接catch()finally()塊以輕松處理錯(cuò)誤的內(nèi)置結(jié)構(gòu)。這種方法比定義附加參數(shù)/重用現(xiàn)有參數(shù)來(lái)處理錯(cuò)誤更容易和更清晰。

    使用Git存儲(chǔ)庫(kù)跟蹤更改

    由于代碼庫(kù)中的手動(dòng)錯(cuò)誤,經(jīng)常會(huì)出現(xiàn)許多錯(cuò)誤。在開(kāi)發(fā)或調(diào)試代碼時(shí),您最終可能會(huì)進(jìn)行不必要的更改,這可能會(huì)導(dǎo)致代碼庫(kù)中出現(xiàn)新的錯(cuò)誤。自動(dòng)化測(cè)試是在每次更改后檢查代碼的好方法。但是,它只能告訴您是否有問(wèn)題。如果你不經(jīng)常備份你的代碼,你最終會(huì)浪費(fèi)時(shí)間試圖修復(fù)一個(gè)以前運(yùn)行良好的函數(shù)或腳本。

    這就是git發(fā)揮作用的地方。通過(guò)適當(dāng)?shù)奶峤徊呗裕梢允褂媚膅it歷史作為備份系統(tǒng)來(lái)查看您的代碼在開(kāi)發(fā)過(guò)程中的演變過(guò)程。您可以輕松地瀏覽舊提交并找出該函數(shù)的版本之前運(yùn)行良好,但在不相關(guān)的更改后拋出錯(cuò)誤。

    然后,您可以恢復(fù)舊代碼或比較兩個(gè)版本以確定哪里出了問(wèn)題?,F(xiàn)代Web開(kāi)發(fā)工具(如GitHub Desktop或GitKraken)可幫助您并排可視化這些更改并快速找出錯(cuò)誤。

    一個(gè)可以幫助您減少錯(cuò)誤的習(xí)慣是 在您對(duì)代碼進(jìn)行重大更改時(shí)運(yùn)行代碼審查。如果您在一個(gè)團(tuán)隊(duì)中工作,您可以創(chuàng)建一個(gè)拉取請(qǐng)求并讓團(tuán)隊(duì)成員徹底審查它。這將幫助您使用第二雙眼睛來(lái)發(fā)現(xiàn)您可能遺漏的任何錯(cuò)誤。

    處理JavaScript錯(cuò)誤的最佳實(shí)踐

    上述方法足以幫助您為下一個(gè)JavaScript應(yīng)用程序設(shè)計(jì)一個(gè)健壯的錯(cuò)誤處理方法。但是,最好在實(shí)施時(shí)記住一些事情,以充分利用您的防錯(cuò)功能。這里有一些提示可以幫助您。

    1. 處理操作異常時(shí)使用自定義錯(cuò)誤

    我們?cè)诒局改系那懊娼榻B了自定義錯(cuò)誤,讓您了解如何根據(jù)應(yīng)用程序的獨(dú)特情況自定義錯(cuò)誤處理。建議盡可能使用自定義錯(cuò)誤而不是泛型Error類(lèi),因?yàn)樗鼮檎{(diào)用環(huán)境提供了有關(guān)錯(cuò)誤的更多上下文信息。

    最重要的是,自定義錯(cuò)誤允許您調(diào)整錯(cuò)誤在調(diào)用環(huán)境中的顯示方式。這意味著您可以根據(jù)需要選擇隱藏特定詳細(xì)信息或顯示有關(guān)錯(cuò)誤的其他信息。

    您可以根據(jù)需要格式化錯(cuò)誤內(nèi)容。這使您可以更好地控制錯(cuò)誤的解釋和處理方式。

    2.不要吞下任何例外

    即使是最資深的開(kāi)發(fā)人員也經(jīng)常犯一個(gè)新手錯(cuò)誤——在他們的代碼中使用異常級(jí)別。

    您可能會(huì)遇到有一段代碼可以選擇運(yùn)行的情況。如果它有效,那就太好了;如果沒(méi)有,你不需要做任何事情。

    在這些情況下,通常很想將這段代碼放在try塊中,并在其上附加一個(gè)空的catch塊。但是,通過(guò)這樣做,您將使那段代碼保持開(kāi)放狀態(tài),從而導(dǎo)致任何類(lèi)型的錯(cuò)誤并逃脫懲罰。如果你有一個(gè)龐大的代碼庫(kù)和許多這樣糟糕的錯(cuò)誤管理結(jié)構(gòu)的實(shí)例,這可能會(huì)變得很危險(xiǎn)。

    處理異常的最好方法是確定所有異常都將被處理的級(jí)別并將它們提高到那里。此級(jí)別可以是控制器(在MVC架構(gòu)應(yīng)用程序中)或中間件(在傳統(tǒng)的面向服務(wù)器的應(yīng)用程序中)。

    通過(guò)這種方式,您將了解在哪里可以找到應(yīng)用程序中發(fā)生的所有錯(cuò)誤并選擇如何解決它們,即使這意味著不對(duì)它們做任何事情。

    3. 對(duì)日志和錯(cuò)誤警報(bào)使用集中策略

    記錄錯(cuò)誤通常是處理錯(cuò)誤的一個(gè)組成部分。那些未能制定集中策略來(lái)記錄錯(cuò)誤的人可能會(huì)錯(cuò)過(guò)有關(guān)其應(yīng)用程序使用情況的寶貴信息。

    應(yīng)用程序的事件日志可以幫助您找出有關(guān)錯(cuò)誤的關(guān)鍵數(shù)據(jù)并幫助快速調(diào)試它們。如果您在應(yīng)用程序中設(shè)置了適當(dāng)?shù)木瘓?bào)機(jī)制,您可以在錯(cuò)誤到達(dá)大部分用戶(hù)群之前知道應(yīng)用程序何時(shí)發(fā)生錯(cuò)誤。

    建議使用預(yù)先構(gòu)建的記錄器或創(chuàng)建一個(gè)以滿足您的需求。您可以配置此記錄器以根據(jù)其級(jí)別(警告、調(diào)試、信息等)處理錯(cuò)誤,并且一些記錄器甚至可以立即將日志發(fā)送到遠(yuǎn)程記錄服務(wù)器。通過(guò)這種方式,您可以觀察應(yīng)用程序的邏輯在活動(dòng)用戶(hù)中的執(zhí)行情況。

    4. 適當(dāng)?shù)赝ㄖ脩?hù)錯(cuò)誤

    在定義錯(cuò)誤處理策略時(shí)要牢記的另一個(gè)要點(diǎn)是牢記用戶(hù)。

    所有干擾您的應(yīng)用程序正常運(yùn)行的錯(cuò)誤都必須向用戶(hù)顯示可見(jiàn)的警報(bào),以通知他們出現(xiàn)問(wèn)題,以便用戶(hù)可以嘗試制定解決方案。如果您知道錯(cuò)誤的快速修復(fù)方法,例如重試操作或注銷(xiāo)并重新登錄,請(qǐng)務(wù)必在警報(bào)中提及它以幫助實(shí)時(shí)修復(fù)用戶(hù)體驗(yàn)。

    如果錯(cuò)誤不會(huì)對(duì)日常用戶(hù)體驗(yàn)造成任何干擾,您可以考慮抑制警報(bào)并將錯(cuò)誤記錄到遠(yuǎn)程服務(wù)器以供以后解決。

    5. 實(shí)現(xiàn)一個(gè)中間件(Node.js)

    Node.js環(huán)境支持中間件向服務(wù)器應(yīng)用程序添加功能。 您可以使用此功能為您的服務(wù)器創(chuàng)建錯(cuò)誤處理中間件。

    使用中間件的最大好處是所有錯(cuò)誤都集中在一個(gè)地方處理。您可以輕松選擇啟用/禁用此設(shè)置以進(jìn)行測(cè)試。

    以下是創(chuàng)建基本中間件的方法:

    const logError = err => {
    console.log("ERROR: " + String(err))
    }
    const errorLoggerMiddleware = (err, req, res, next) => {
    logError(err)
    next(err)
    }
    const returnErrorMiddleware = (err, req, res, next) => {
    res.status(err.statusCode || 500)
    .send(err.message)
    }
    module.exports = {
    logError,
    errorLoggerMiddleware,
    returnErrorMiddleware
    }

    然后,您可以在您的應(yīng)用程序中使用此中間件,如下所示:

    const { errorLoggerMiddleware, returnErrorMiddleware } = require('./errorMiddleware')
    app.use(errorLoggerMiddleware)
    app.use(returnErrorMiddleware)

    您現(xiàn)在可以在中間件中定義自定義邏輯以適當(dāng)?shù)靥幚礤e(cuò)誤。您不再需要擔(dān)心在整個(gè)代碼庫(kù)中實(shí)現(xiàn)單個(gè)錯(cuò)誤處理結(jié)構(gòu)。

    6. 重新啟動(dòng)您的應(yīng)用程序以處理程序員錯(cuò)誤(Node.js)

    當(dāng)Node.js應(yīng)用程序遇到程序員錯(cuò)誤時(shí),它們可能不一定會(huì)拋出異常并嘗試關(guān)閉應(yīng)用程序。此類(lèi)錯(cuò)誤可能包括由程序員錯(cuò)誤引起的問(wèn)題,例如高CPU消耗、內(nèi)存膨脹或內(nèi)存泄漏。處理這些問(wèn)題的最佳方法是通過(guò)Node.js集群模式或PM2等獨(dú)特工具使應(yīng)用程序崩潰,從而優(yōu)雅地重新啟動(dòng)應(yīng)用程序。這可以確保應(yīng)用程序不會(huì)因用戶(hù)操作而崩潰,從而呈現(xiàn)糟糕的用戶(hù)體驗(yàn)。

    7. 捕獲所有未捕獲的異常(Node.js)

    您永遠(yuǎn)無(wú)法確定您已經(jīng)涵蓋了您的應(yīng)用程序中可能出現(xiàn)的所有錯(cuò)誤。因此,實(shí)施備用策略以從您的應(yīng)用程序中捕獲所有未捕獲的異常非常重要。

    您可以這樣做:

    process.on('uncaughtException', error => {
    console.log("ERROR: " + String(error))
    // other handling mechanisms
    })

    您還可以確定發(fā)生的錯(cuò)誤是標(biāo)準(zhǔn)異常還是自定義操作錯(cuò)誤。根據(jù)結(jié)果??,您可以退出進(jìn)程并重新啟動(dòng)它以避免意外行為。

    8. 捕獲所有未處理的Promise Rejections (Node.js)

    與您永遠(yuǎn)無(wú)法涵蓋所有??可能的異常類(lèi)似,您很有可能會(huì)錯(cuò)過(guò)處理所有可能的Promise Rejections。但是,與異常不同,Promise Rejection不會(huì)引發(fā)錯(cuò)誤。

    因此,一個(gè)重要的Promise Rejection可能會(huì)作為警告而溜走,并使您的應(yīng)用程序面臨遇到意外行為的可能性。因此,實(shí)現(xiàn)一個(gè)回退機(jī)制來(lái)處理Promise Rejection是至關(guān)重要的。

    您可以這樣做:

    const promiseRejectionCallback = error => {
    console.log("PROMISE REJECTED: " + String(error))
    }
    process.on('unhandledRejection', callback)
    

    小結(jié)

    與任何其他編程語(yǔ)言一樣,JavaScript中的錯(cuò)誤非常頻繁且自然。在某些情況下,您甚至可能需要故意拋出錯(cuò)誤以向用戶(hù)指示正確的響應(yīng)。因此,了解它們的解剖結(jié)構(gòu)和類(lèi)型非常重要。

    此外,您需要配備正確的工具和技術(shù)來(lái)識(shí)別和防止錯(cuò)誤導(dǎo)致您的應(yīng)用程序崩潰。

    在大多數(shù)情況下,對(duì)于所有類(lèi)型的JavaScript應(yīng)用程序來(lái)說(shuō),通過(guò)仔細(xì)執(zhí)行來(lái)處理錯(cuò)誤的可靠策略就足夠了。


    文章標(biāo)題:處理JavaScript錯(cuò)誤的權(quán)威指南
    文章來(lái)源:http://www.5511xx.com/article/dghhhgj.html