JavaScript錯誤處理專題

當JavaScript 引擎執行 JavaScript 代碼時,會發生各種錯誤:可能是語法錯誤,通常是程序員造成的編碼錯誤或錯別字;可能是拼寫錯誤或語言中缺少的功能(可能由於瀏覽器差異);可能是由於來自服務器或用戶的錯誤輸出而導致的錯誤;也可能是由於許多其他不可預知的因素。那麼js有沒有好的可以檢測錯誤的呢?

JS本身是動態語言,因此人們普遍認為它是一種最難於調試的編程語言。腳本出錯時,由於沒有上下文信息,讓人摸不著頭腦,ECMAScript 第 3 版致力於解決這個問題,專門引入了try-catch和throw等語句以及一些錯誤類型,意在讓開發人員能夠適當地處理錯誤,提升開發效率。

1. Error 實例對象

JavaScript 解析或運行時,一旦發生錯誤,引擎就會拋出一個錯誤對象。JavaScript 原生提供Error構造函數,所有拋出的錯誤都是這個構造函數的實例。

<code>

var

err =

new

Error

(

'出錯了'

); err.message /<code>

拋出Error實例對象以後,整個程序就中斷在發生錯誤的地方,不再往下執行。


Error具有下面一些主要屬性:

  • description: 錯誤描述 (僅IE可用).
  • fileName: 出錯的文件名 (僅Mozilla可用).
  • lineNumber: 出錯的行數 (僅Mozilla可用).
  • message: 錯誤信息 (在IE下同description)
  • name: 錯誤類型.
  • number: 錯誤代碼 (僅IE可用).
  • stack: 像Java中的Stack Trace一樣的錯誤堆棧信息 (僅Mozilla可用).


2. 原生錯誤類型

Error 實例對象是最一般的錯誤類型,在它的基礎上,JavaScript 還定義了其他 6 種錯誤對象。也就是說,存在Error 的 6 個派生對象。

2.1 SyntaxError 對象

SyntaxError 對象是解析代碼時發生的語法錯誤。

<code> 

var

1

a;

console

.log

'hello'

); /<code>

2.2 ReferenceError 對象

ReferenceError 對象是引用一個不存在的變量時發生的錯誤。

<code> 
unknownVariable
 
/<code>

另一種觸發場景是,將一個值分配給無法分配的對象。

<code> 
console.

log

() =

1

this

=

1

/<code>

2.3 RangeError 對象

RangeError 對象是一個值超出有效範圍時發生的錯誤。主要有幾種情況,一是數組長度為負數,二是 Number 對象的方法參數超出範圍,以及函數堆棧超過最大值。

<code> 

new

Array

(

-1

) /<code>

2.4 TypeError 對象

TypeError 對象是變量或參數不是預期類型時發生的錯誤。比如,對字符串、布爾值、數值等原始類型的值使用 new 命令,就會拋出這種錯誤,因為 new 命令的參數應該是一個構造函數。

<code>

new

123

var

obj = {}; obj.unknownMethod() /<code>

2.5 URIError 對象

URIError 對象是 URI 相關函數的參數不正確時拋出的錯誤,主要涉及encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()、escape()和unescape()這六個函數。

2.6 EvalError 對象

eval函數沒有被正確執行時,會拋出EvalError錯誤。該錯誤類型已經不再使用了,只是為了保證與以前代碼兼容,才繼續保留。

2.7 總結

以上這6種派生錯誤,連同原始的 Error 對象,都是構造函數。這些構造函數都接受一個參數,代表錯誤提示信息(message)。

<code>

var

err1 =

new

Error

(

'出錯了!'

);

var

err2 =

new

RangeError

(

'出錯了,變量超出有效範圍!'

);

var

err3 =

new

TypeError

(

'出錯了,變量類型無效!'

); err1.message err2.message err3.message /<code>

3. throw 語句

throw 語句的作用是主動中斷程序執行,拋出一個錯誤。

<code>

var

x =

-1

if

(x <=

0

) {

throw

new

Error

(

'x 必須為正數'

); } /<code>

上面代碼中,如果變量 x 小於等於 0,就手動拋出一個錯誤,告訴用戶 x 的值不正確,整個程序就會在這裡中斷執行。可以看到,throw 拋出的錯誤就是它的參數,這裡是一個 Error 實例。

throw 可以拋出任何類型的值。也就是說,它的參數可以是任何值。

<code> 

throw

'Error!'

;

throw

42

; /<code>

對於 JavaScript 引擎來說,遇到throw 語句,程序就中止了。引擎會接收到throw拋出的信息,可能是一個錯誤實例,也可能是其他類型的值。

4. try...catch 結構

一旦發生錯誤,程序就中止執行了。JavaScript 提供了 try...catch 結構,允許對錯誤進行處理,選擇是否往下執行。

如果你不確定某些代碼是否會報錯,就可以把它們放在 try...catch 代碼塊之中,便於進一步對錯誤進行處理。

<code>

try

{

throw

"出錯了"

; }

catch

(e) { console.

log

(

111

); } console.

log

(

222

); /<code>

上面代碼中,try 代碼塊拋出的錯誤,被catch代碼塊捕獲後,程序不會中斷,會按照正常流程繼續執行下去。

5. finally 代碼塊

try...catch 結構允許在最後添加一個finally代碼塊,表示不管是否出現錯誤,都必需在最後運行的語句。

<code>

function

cleansUp

(

)

{

try

{

throw

new

Error

(

'出錯了……'

);

console

.log(

'此行不會執行'

); }

finally

{

console

.log(

'完成清理工作'

); } } cleansUp() /<code>

上面代碼中,由於沒有 catch 語句塊,一旦發生錯誤,代碼就會中斷執行。中斷執行之前,會先執行 finally 代碼塊,然後再向用戶提示報錯信息。

下面的例子說明,return 語句的執行是排在finally代碼之前,只是等finally代碼執行完畢後才返回。

<code>

var

count =

0

;

function

countUp

(

)

{

try

{

return

count; }

finally

{ count++; } } countUp() count /<code>

下面的例子充分反映了 try...catch...finally 這三者之間的執行順序。

<code>

function

f

(

)

{

try

{

console

.log(

0

);

throw

'bug'

; }

catch

(e) {

console

.log(

1

);

return

true

;

console

.log(

2

); }

finally

{

console

.log(

3

);

return

false

;

console

.log(

4

); }

console

.log(

5

); }

var

result = f(); result /<code>

上面代碼中,catch 代碼塊結束執行之前,會先執行 finally 代碼塊。

finally代碼塊用法的典型場景

<code>

openFile

();

try

{

writeFile

(Data); }

catch

(e) {

handleError

(e); }

finally

{

closeFile

(); } /<code>

上面代碼首先打開一個文件,然後在 try 代碼塊中寫入文件,如果沒有發生錯誤,則運行 finally 代碼塊關閉文件;一旦發生錯誤,則先使用 catch 代碼塊處理錯誤,再使用 finally 代碼塊關閉文件。


JavaScript錯誤處理專題


分享到:


相關文章: