亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

JavaScript錯誤處理操作實例詳解

2024-05-06 16:47:35
字體:
來源:轉載
供稿:網友

本文實例講述了JavaScript錯誤處理操作。分享給大家供大家參考,具體如下:

良好的錯誤處理機制可以讓用戶得到及時的提醒,所以讓我們來看看 JavaScript 提供了哪些針對錯誤處理的工具和方法吧O(∩_∩)O~

1 try-catch 語句

ECMA-262 第 3 版引入了 try-catch 語句,這時 JavaScript 處理異常的標準方式:

try{  //可能會導致錯誤的代碼} catch (error){  //錯誤處理}

如果 try 塊中的代碼發生了錯誤,會立即執行 catch 塊的代碼。 catch 塊有一個包含錯誤信息的對象,它有一個 message 屬性,表示的是瀏覽器給出的錯誤消息:

<script type="text/javascript">  try {    window.someNonexistenceFunction();  } catch (error) {    console.log(error.message);  }</script>

message 屬性是所有的瀏覽器都支持的屬性,所以在跨瀏覽器編程中,最好只使用這個屬性。

1.1 finally 子句

finally 子句是可選的,如果使用了 finally 子句,里面包含的代碼是絕對會被執行的!甚至連 return 語句都無法阻止它被執行:

<script type="text/javascript">  function testFinally() {    try {      return 2;    } catch (error) {      return 1;    } finally {      return 0;    }  }  console.log(testFinally());//0</script>

IE7 及更早的版本有一個 bug:除非有 catch 子句,否則 finally 中的代碼永遠不會被執行!IE8 修復了這個 bug。

注意:只要在代碼中使用了 finally 子句,那么不管 return 放在 try 還是 catch 語句中,都會被忽略!

1.2 錯誤類型

當錯誤發生時,會拋出相應類型的錯誤對象。ECMA-262 定義了 7 種錯誤類型:

  • Error
  • EvalError
  • RangeError
  • ReferenceError
  • SyntaxError
  • TypeError
  • URIError

1.2.1 Error

Error 是基類型,即其他的錯誤類型都是從 Error 繼承來的。可以利用 Error 來自定義錯誤類型。

1.2.2 EvalError

EvalError 是在使用 eval() 函數發生異常時被拋出。怎么才算是異常呢?如果沒有把 eval() 當作函數來使用,就會拋出 EvalError:

new eval();//拋出 EvalErroreval = foo;//拋出 EvalError

實際開發中很少這樣使用 eval() 函數的(除非腦袋秀逗了O(∩_∩)O~),所以很少會遇到 EvalError。

1.2.3 RangeError

RangeError 會在數值超出規定范圍時被拋出。比如在定義數組時,指定了數組不支持的數組項數,就會拋出這個錯誤:

var item1 = new Array(-20);//拋出 RangeErrorvar item1 = new Array(Number.MAX_VALUE);//拋出 RangeError

1.2.4 ReferenceError

找不到對象時,會拋出 ReferenceError(這就是瀏覽器的知名的 “object expected” 錯誤)。一般在訪問不存在的變量時,會拋出這個錯誤:

var obj = x;//x 還未被聲明,所以拋出 ReferenceError

1.2.5 SyntaxError

如果把帶著錯誤語法的字符串傳入 eval() 函數時,就會拋出 SyntaxError:

eval("a ++ b");//拋出 SyntaxError

在 eval() 函數之外的語法錯誤,會導致 JavaScript 立即停止執行,所以不會拋出這個錯誤!

1.2.6 TypeError

如果變量中保存著意外的類型,或者訪問不存在的方式時,就會拋出 TypeError。這個錯誤比較常見:

var o = new 10;//拋出 TypeErroralert("name" in true);//拋出 TypeErrorFunction.prototype.toString.call("name");//拋出 TypeError

如果傳遞給函數的參數類型與預期類型不符,也會拋出這個錯誤。

1.2.7 URIError

使用 encodeURI() 或者 decodeURI() 時,URI 的格式不正確,就會拋出 URIError 錯誤。一般很少發生,因為這兩個函數有著非常高的容錯性O(∩_∩)O~

可以針對這些錯誤類型進行恰當的處理:

try{  someFunction();} catch (error){  if (error instanceof TypeError){    //處理類型錯誤  }  ...}

因為包含在 message 中的消息會因瀏覽器而異,所以在跨瀏覽器編程中,最好直接檢查這些錯誤類型。

1.3 合理使用 try-catch

try-catch 最適合用于那些我們無法控制的錯誤,比如使用了一個開源庫中的函數,而我們無法修改源代碼的情況。

而對于自定義的函數,驗證函數參數類型是否合法的情況,就不應該使用 try-catch,因為這個函數是我們可以修改的,在使用參數前先進行驗證才是正途。

2 拋出錯誤

throw 操作符可以拋出自定義的錯誤,必須要指定一個值,這個值可以是任意類型。代碼在遇到 throw 操作符時,會立即停止執行。只有在 try-catch 語句捕獲到被拋出的值時,才會繼續執行。

通過使用之前說過的內置錯誤類型,可以模擬瀏覽器錯誤。這些錯誤類型的構造函數都接收一個參數,即實際的錯誤消息:

throw new Error("Something bad happened.");

最常使用這些錯誤類型來創建自定義的錯誤消息:Error、RangeError、ReferenceError 和 TypeError。

也可以利用原型鏈,通過繼承 Error 來創建自定義消息。比如,這里為新創建的錯誤類型指定了 name 和 message 屬性:

<script type="text/javascript">  function CustomError(message) {    this.name = "CustomError";    this.message = message;  }  CustomError.prototype = new Error();  throw new CustomError("My message");</script>

這樣創建的自定義錯誤與瀏覽器錯誤并不同,所以可是很有用的哦O(∩_∩)O~

注意: IE 只有在拋出 Error 對象時才會顯示自定義的錯誤消息!其他錯誤對象,它只會顯示 “exception thrown and not caught”。

2.1 拋出錯誤的時機

應該在已知的、某種特定錯誤條件下(會導致函數無法正常執行),拋出自定義的錯誤:

<script type="text/javascript">  function process(values) {    if (!(values instanceof Array)) {      throw new Error("process():Argument must be an array.");    }    values.sort();    for (var i = 0, len = values.length; i < len; i++) {      if (values[i] > 100) {        return values[i];      }    }    return -1;  }  process("hi");</script>

如果給上面的函數傳入一個字符串參數,那么 sort() 就會拋錯,所以我們在這里加入了帶有適當消息的自定義錯誤。這對于一個有著幾千行腳本代碼的項目來說,可以顯著地提升代碼的可維護性O(∩_∩)O~

錯誤消息時包含了函數名稱以及為什么會發生錯誤的明確描述,是不是很清晰呀O(∩_∩)O~

在開發時,要注意函數可能失敗的因素,把這些因素都加上自定義錯誤吧!良好的錯誤處理機制是確保代碼只發生我們定義的錯誤。

2.2 拋出錯誤與使用 try-catch

建議在拋出錯誤時盡量提供詳盡的信息,因為我們拋出錯誤不就是為了在維護時,能夠知道錯誤發生的具體位置和具體原因的嗎?

3 錯誤事件

任何沒有通過 try-catch 處理的錯誤都會觸發 window 對象的 error 事件(IE、Firfox 和 chrome 支持)。它接收 3 個參數:錯誤消息、錯誤所在的 URL 和行號。一般只有錯誤消息有用。只能通過 DOM0 級技術來指定 onerror 事件處理程序,如果返回 false,就可以阻止瀏覽器報告錯誤的默認行為:

<script type="text/javascript">  window.onerror= function (message,url,line) {    console.log(message);    return false;  }</script>

這個函數其實就是整個文檔的 try-catch 語句,它可以捕獲所有沒有被處理的運行時錯誤。理想情況下,錯誤都被包含在 try-catch 語句中,所以不會使用到它。

注意: 不同的瀏覽器下,這個函數的處理方式不同。在 IE 中,發生了 onerror 事件,代碼仍會執行,所有的變量和數據都會保留。但在 Firefox 中,代碼會停止執行,而且之前所有的變量和數據都會被銷毀!

圖像也支持 error 事件。如果圖像的 src 屬性中的 URL 無法返回被識別的圖像格式時,就會觸發持 error 事件。這時的 error 事件會返回一個以圖像為目標的 event 對象:

<script type="text/javascript">  var image = new Image();  EventUtil.addHandler(image, "load", function (event) {    console.log("Image loaded!");  });  EventUtil.addHandler(image, "error", function (event) {    console.log("Image not loaded!");  });  image.src = "smilex.gif";//實際并不存在</script>

注意,如果發生了 error 事件,那么這個圖像的下載過程就已經結束咯。

4 常見的錯誤類型

因為 JavaScript 是松散類型的語言,所以錯誤只會在代碼運行期間發生。一般情況下,我們需要重點關注以下三種錯誤:

① 類型轉換錯誤
② 數據類型錯誤
③ 通信錯誤

4.1 類型轉換錯誤

在使用相等(==)或不相等(!==),或者在 if、for 或 while 中使用了非布爾值時,最常發生類型轉換錯誤。

所以建議使用全等(===)和不全等(!==)來避免類型轉換操作。

if 等語句會自動把任何值都轉換為布爾值:

function concat(str1, str2, str3){  var result = str1 + str2;  if (str3){//不要這樣?。?!    result +=str3;  }  return result;}

這個函數是想拼接兩個或三個字符串,然后返回結果。所以這里的第三個參數是可選的,,所以必須要檢查。如果我們在調用這個函數時,只用到前兩個參數,這意味著第三個參數因為是未使用過的命名變量,所以被自動賦值給 undefine,而 undefine 在 if 中會被自動轉換為 false,這樣可以。但是,如果第三個參數傳入數值 0,在 if 中會被自動轉換為 false,那么就不會被加到 result 中!所以我們要進行檢查:

function concat(str1, str2, str3){  var result = str1 + str2;  if (typeof str3 == "string"){    result +=str3;  }  return result;}

4.2 數據類型錯誤

function getQueryString(url){  var pos = url.indexOf("?");  if (pos > -1){    return url.substring(pos + 1);  }  return "";}

這個函數打算返回給定 URL 中的查詢字符串。但如果傳入非字符串類型的參數,就會導致錯誤。所以要加上類型判斷:

function getQueryString(url){  if(typeof url == "string"){    var pos = url.indexOf("?");    if (pos > -1){      return url.substring(pos + 1);    }  }  return "";}

還有,如果在流控制語句中使用非布爾值也會導致數據類型錯誤:

function reverseSort(values){  if (values){//非數組值都會報錯    values.sort();    values.reverse();  }}

另一種錯誤是將參數與 null 進行比較,這只能確保參數不是 null 和 undefined,也不建議將參數與 undefined 進行比較。

還有一種錯誤是,只針對某一特性進行檢測:

function reverseSort(values){  if (typeof values.sort == "function"){    values.sort();    values.reverse();  }}

上面的函數,如果傳入帶有 sort() 方法的對象,就會通過檢測,但會在調用 reverse() 方法時報錯!所以這里最好是使用 instanceof 來檢測:

function reverseSort(values){  if (values instanceof Array){    values.sort();    values.reverse();  }}

總的來說,基本類型的值使用 typeof 檢測,而對象的值使用 instanceof 來檢測。特別是面向公眾的 API,一定要執行類型檢查,以確保函數始終能夠正常執行。

4.3 通信錯誤

JavaScript 與服務器之間的任何一次通信,就有可能會產生錯誤。

一種通信錯誤是發送了不正確的 URL 格式數據。一般是沒有使用 encodeURIComponent() 對數據進行編碼,可以使用這里的函數來處理查詢字符串:

/** * 添加查詢字符串 * @param url URL * @param name 參數名 * @param value 參數值 * @returns {*} */function addQueryStringArg(url, name, value) {  if (url.indexOf("?") == -1) {    url += "?";  } else {    url += "&";  }  url += encodeURIComponent(name) + "=" + encodeURIComponent(value);  return url;}

盡量使用這個函數,就可以確保編碼正確。

5 區分致命錯誤與非致命錯誤

非致命錯誤可以根據以下列出的一個或多個條件來確定:

  • 不影響用戶的主要任務;
  • 只影響頁面的一部分;
  • 可以恢復;
  • 重復操作可以消除錯誤。

而致命錯誤也可以根據以下列出的一個或多個條件來確定:

  • 無法繼續執行;
  • 影響到了用戶的主要操作;
  • 導致其他連帶的錯誤。

如果發生了致命錯誤,要立即發送消息通知用戶,告訴他們無法再繼續操作咯。如果必須刷新頁面才會恢復,也必須通知用戶,并提供了可刷新頁面的按鈕。

比如,在大型網站中,可能有多個互不依賴的模塊,它們是類似這樣初始化的:

for (var i=0, len=mods.length; i<len; i++){  mods[i].init();}

這樣做的問題是,如果有一個模塊發生錯誤,那么就會導致后續的其它模塊無法被初始化,從而導致致命的錯誤!我們這樣改造下,讓致命的錯誤變成非致命的錯誤:

for (var i=0, len=mods.length; i<len; i++){  try{    mods[i].init();  } catch (ex){    ...  }}

6 把錯誤記錄到服務器

建議集中保存錯誤日志,這樣可以方便后續查找錯誤的原因。所以我們可以把 JavaScript 錯誤發送給服務器,讓服務器保存起來。這樣把前后端的錯誤集中起來管理,就可以很方便地對數據進行分析咯O(∩_∩)O~

首先先在服務器上創建一個接口,用于接收頁面發送的錯誤數據:

/** * 記錄 JavaScript 錯誤 * @param sev 嚴重程度,比如:nonfatal * @param msg 錯誤消息 */function logError(sev,msg){  var img=new Image();  img.src="log.action?sev="+encodeURIComponent(sev)+"&msg="+encodeURIComponent(msg);}

使用 Image 對象來發送請求,有這些好處:

  • 所有的瀏覽器都支持 Image 對象,包含那些不支持 XMLHttpRequest 對象的瀏覽器。
  • 可以避免跨域限制。比如可以使用一臺日志服務器專門接收多臺 web 服務器拋出的錯誤。

只要是使用了 try-catch 語句,就要把錯誤記錄到日志中:

for (var i=0, len=mods.length; i<len; i++){  try{    mods[i].init();  } catch (ex){    logError("nonfatal","模塊初始化失?。?quot;+ex.message);  }}

第二個參數是上下文信息以及 JavaScript 的錯誤消息,帶上上下文信息可以方便分析導致錯誤的真正原因。

希望本文所述對大家JavaScript程序設計有所幫助。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩高清av一区二区三区| 91久久国产综合久久91精品网站| 91在线视频九色| 亚洲人成五月天| 久久九九国产精品怡红院| 亚洲欧美日韩在线高清直播| 日韩中文字幕在线精品| 精品中文字幕在线观看| 国产a∨精品一区二区三区不卡| 九色精品美女在线| 人人做人人澡人人爽欧美| 日韩精品中文字幕有码专区| 午夜精品在线观看| 精品久久久久久久久久ntr影视| 国产美女精品视频| 亚洲性猛交xxxxwww| 亚洲欧洲在线看| 欧美裸体男粗大视频在线观看| 欧美午夜激情小视频| 久久久亚洲成人| 亚洲系列中文字幕| 亚洲国产精品资源| 欧美精品激情视频| 欧美激情高清视频| 国产一区二区欧美日韩| 色偷偷av亚洲男人的天堂| 国内精品小视频| 欧美精品18videos性欧| 亚洲人成欧美中文字幕| 国产性猛交xxxx免费看久久| 日韩av在线不卡| 成人亚洲综合色就1024| 欧美日韩国产限制| 日韩欧美在线免费| 欧美性高跟鞋xxxxhd| 日韩精品视频在线观看免费| 亚洲精品91美女久久久久久久| 国产精品1区2区在线观看| 伊人久久免费视频| 久久亚洲精品国产亚洲老地址| 国产精品免费看久久久香蕉| 青草青草久热精品视频在线观看| 91成人在线视频| 97色在线视频观看| 日韩av在线网| 日韩中文在线不卡| 久久久久久com| 国产精品网站视频| 狠狠躁18三区二区一区| 欧美在线观看www| 精品久久久久久久久久久久久| 91理论片午午论夜理片久久| 538国产精品一区二区免费视频| 亚洲第一色中文字幕| 欧美另类老肥妇| 欧美性猛交xxxx乱大交蜜桃| 国产精品美女久久久免费| 91福利视频在线观看| 欧美在线一区二区视频| 亚洲风情亚aⅴ在线发布| 一区二区三区视频观看| 亚洲欧美另类人妖| 91丨九色丨国产在线| 国产综合在线看| 91免费人成网站在线观看18| 中文字幕在线看视频国产欧美在线看完整| 久久中文字幕在线视频| 色综合男人天堂| 91视频免费在线| 久久99热这里只有精品国产| 亚洲国产日韩欧美在线图片| 久久久亚洲精选| 欧美高清一级大片| 欧美日韩亚洲系列| 日日骚av一区| 精品国模在线视频| 国模私拍视频一区| 国产精品免费在线免费| 91极品女神在线| 久久视频在线视频| 在线精品播放av| 国产热re99久久6国产精品| 国产综合福利在线| 欧美一级淫片aaaaaaa视频| 26uuu另类亚洲欧美日本一| 亚洲字幕一区二区| 亚洲tv在线观看| 日韩欧美主播在线| 国产视频在线一区二区| 亚洲精品中文字| 欧美午夜片在线免费观看| 日韩av大片在线| 日韩激情av在线播放| 欧美性色xo影院| 久久精品国产亚洲一区二区| 青青草原一区二区| 另类天堂视频在线观看| 4p变态网欧美系列| 亚洲国产女人aaa毛片在线| 亚洲成人网久久久| 精品欧美一区二区三区| 久久久久久久久电影| 亚洲精品少妇网址| 日韩在线观看网站| 亚洲第一精品福利| 色先锋资源久久综合5566| 欧美成人激情图片网| 久久久久久有精品国产| 隔壁老王国产在线精品| 久久亚洲国产精品| 欧美在线视频观看免费网站| 日本欧美国产在线| 55夜色66夜色国产精品视频| 精品av在线播放| 欧美性xxxx极品高清hd直播| 日韩午夜在线视频| 欧洲日韩成人av| 日韩av影片在线观看| 成人网页在线免费观看| 日韩成人在线视频观看| 精品国产网站地址| 欧美激情视频一区二区三区不卡| 欧美一区三区三区高中清蜜桃| 欧美性资源免费| 亚洲男人天堂网| 中日韩美女免费视频网站在线观看| 亚洲第一偷拍网| 国产偷亚洲偷欧美偷精品| 亚洲一区二区中文| 九九精品视频在线观看| 欧美巨乳美女视频| 国产精品视频一区二区三区四| 精品久久久国产精品999| 国产精品男人爽免费视频1| 国产美女久久精品| 不卡伊人av在线播放| 亚洲欧美激情四射在线日| 91国在线精品国内播放| 欧美一级片久久久久久久| 欧美一区二区三区精品电影| 国产精品免费久久久| 中文字幕不卡av| 97精品免费视频| 欧美激情精品久久久久久大尺度| 88国产精品欧美一区二区三区| 中文字幕欧美视频在线| 亚洲男人天堂网| 国产福利成人在线| 8x海外华人永久免费日韩内陆视频| 尤物九九久久国产精品的特点| 国内精品在线一区| 欧美激情视频在线观看| 欧美日韩中文字幕在线视频| 亚洲精品视频在线播放| 精品成人久久av| 91在线观看免费高清| 成人免费在线视频网站| 伊人久久五月天| 精品国产一区久久久| 亚洲成人激情在线| 97精品视频在线播放| 欧美日韩爱爱视频| 一区二区三区高清国产| 成人黄色免费网站在线观看|