JavaScript中的異常處理

一、什麼是例外處理

當 JavaScript程序在運行中發生瞭諸如數組索引越界、類型不匹配或者語法錯誤時,JavaScript解釋器就會引發例外處理。 ECMAScript定義瞭六種類型的錯誤,除此之外,我們可以使用Error對象和throw語句來創建並引發自定義的例外處理信息。

通過運用例外處理技術,我們可以實現用結構化的方式來響應錯誤事件的發生,讓例外處理代碼與正常腳本代碼科學分離,最終使我們能夠集中精力編寫完成主要功能的核心程序。

二、使用 try…catch…finally 執行例外處理

在JavaScript中,我們使用try…catch…finally語句來執行例外處理,即通過它來捕捉錯誤發生後導致的例外或者執行throw語句產生的例外。

它的基本語法如下:

try {
   // 此處是可能產生例外的語句
} catch(error) {
   // 此處是負責例外處理的語句
} finally {
   // 此處是出口語句
}

上述代碼中,try塊中的語句首先被執行。如果運行中發生瞭錯誤,控制就會轉移到位於catch塊中語句,其中括號中的error參數被作為例外變量傳遞。否則,catch塊的語句被跳過不執行。

無論是發生錯誤時catch塊中的語句執行完畢,或者沒有發生錯誤try塊中的語句執行完畢,最後將執行 finally塊中的語句。

下面我們來看一個例子:

try {
   document.writeln("開始執行try塊語句 ---> ")
   document.writeln("還沒有發生例外 ---> ")
   alert(eval(prompt("輸入一個值:","")))
} catch(err) {
   document.writeln("捕捉到例外,開始執行catch塊語句 --->");
   document.writeln("錯誤名稱: " + err.name+" ---> ");
   document.writeln("錯誤信息: " + err.message+" ---> ");
} finally {
   document.writeln("開始執行finally塊語句")
}

四、例外的表現形式:Error對象

在JavaScript,例外是作為Error對象出現的。

Error對象有兩個屬性:name屬性表示例外的類型,message屬性表示例外的含義。根據這些屬性的取值,我們可以決定處理例外的方式,比如:

function evalText() {
  try {
    alert(eval(prompt("Enter JavaScript to evaluate:","")))
  } catch(err) {
   if(err.name == "SyntaxError")
       alert("Invalid expression")
   else 
      alert("Cannot evaluate")
  }
}

上面的代碼將對用戶輸入的內容進行表達式求值,然後顯示出來。如果在求值過程中發生瞭SyntaxErroe類型錯誤,那麼就會顯示給用戶“Invalid expression”的信息;否則,用戶得到信息“Cannot evaluate”。

Error.name的取值一共有六種,如下:

  • EvalError:eval()的使用與定義不一致
  • RangeError:數值越界
  • ReferenceError:非法或不能識別的引用數值
  • SyntaxError:發生語法解析錯誤
  • TypeError:操作數類型錯誤
  • URIError:URI處理函數使用不當

五、定制例外信息

上述的六種Error類型基本上覆蓋瞭腳本程序運行時所可能發生的錯誤。除瞭這些類型以外,我們還可以使用Error構造器來自定義例外類型。其語法如下:

myError = new Error(msg)

其中msg參數表示所定義的新例外的message屬性值。同時,我們還可以創建新的對象類型以作為Error的子類型:

function MyError(msg) {
   this.name = "MyError"
   this.message = msg
}
MyError.prototype = new Error;

然後,我們就可以創建自定義錯誤子類的實例:

myError = new MyError("My error message")

六、觸發例外

創建一個Error對象後,就可以使用throw語句來觸發相應的例外。Throw的語法如下:

throw errObj

errObj必須是一個Error對象或者Error的子類型。在try塊代碼中觸發一個例外後,控制將直接轉入catch塊。

下面的代碼中,在try塊中觸發瞭一個例外,設置例外信息為“oops”,然後控制轉移到catch塊:

var s
try {
   s = "one "
   throw new Error("oops")
   s += "two"
} 
catch(err) {
   s += err.message
}
s += " three"
alert(s)

編寫代碼來觸發例外的優點很多,比如有利於自定義錯誤類型,快速轉入catch塊執行,以及下面要介紹的在嵌套例外中將錯誤傳遞到外層。

七、嵌套例外處理

JavaScript支持多層次的嵌套例外處理。一般情況下,我們可以在內部例外處理的catch代碼塊中捕捉並處理錯誤,然後再次觸發例外,這樣就可進一步在外部例外處理的catch代碼塊中做更加深入的處理。下面來看看一個嵌套例外處理的例子:

var inner;
var outer;
try {
   document.writeln("Beginning outer try block, no exceptions yet");
   try{
      document.writeln("Beginning inner try block, no exceptions yet");
      // 生成一個引用錯誤
      document.writeln(undefinedVariable)
      document.writeln("Finished inner try block with no exceptions");
   } catch(inner) {
      // 內部例外處理
      document.writeln("Exception caught, beginning inner catch block");
      document.writeln("Error type: " + inner.name);
      document.writeln("Error message: " + inner.message);
      throw inner;
      document.writeln("No exceptions thrown in inner catch block");
   } finally {
      document.writeln("Executing inner finally block");
   }
   document.writeln("Finished outer try block with no exceptions");
} catch(outer) {
   // 外部例外處理
   document.writeln("Exception caught, beginning outer catch block");
   document.writeln("Error type: " + outer.name);
   document.writeln("Error message: " + outer.message);
} finally {
   document.writeln("Executing outer finally block");
}

執行後的輸出結果如下:

Beginning outer try block, no exceptions yet 
Beginning inner try block, no exceptions yet 
Exception caught, beginning inner catch block 
Error type: ReferenceError 
Error message: undefinedVariable is not defined 
Executing inner finally block 
Exception caught, beginning outer catch block 
Error type: ReferenceError 
Error message: undefinedVariable is not defined 
Executing outer finally block

嵌套例外處理的好處在於使我們能夠很好地分階段處理錯誤,內部例外處理可以負責解決由錯誤引發的腳本代碼問題,外部例外處理則用於負責提供給用戶的反饋信息或者對例外信息進行日志記錄。

到此這篇關於JavaScript異常處理的文章就介紹到這瞭。希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: