技術(shù)頻道導(dǎo)航
HTML/CSS
.NET技術(shù)
IIS技術(shù)
PHP技術(shù)
Js/JQuery
Photoshop
Fireworks
服務(wù)器技術(shù)
操作系統(tǒng)
網(wǎng)站運營

贊助商

分類目錄

贊助商

最新文章

搜索

js:try...catch...finally捕獲錯誤處理的用法實例

作者:admin    時間:2021-4-28 1:2:14    瀏覽:

我們在JS編程時,特別在調(diào)試階段,捕獲錯誤是非常有必要的,這將大大提高我們的勘錯效率。而要把程序編寫得更安全堅固,錯誤處理也必不可少。

JS存在一種語法構(gòu)造try...catch,該語法構(gòu)造使我們可以“捕獲”錯誤,這使腳本可以執(zhí)行得更加合理而不會因遇到“死亡腳本”導(dǎo)致程序執(zhí)行失敗。

 js: try-catch-finally捕獲錯誤
js: try-catch-finally捕獲錯誤

“ try…catch”語法

try...catch構(gòu)造有兩個主要塊:trycatch

try {

  // 代碼...

} catch (err) {

  // 錯誤處理

}

它是這樣的:

首先,執(zhí)行try {...}中的代碼。

如果沒有錯誤,則將忽略catch(err):執(zhí)行到達try的結(jié)尾并繼續(xù),跳過catch。

如果發(fā)生錯誤,則try執(zhí)行將停止,控制流向catch(err)的開頭。該err變量(我們可以使用它的任何名稱)將包含發(fā)生了什么詳細的錯誤對象。

因此,try {...}塊內(nèi)的錯誤不會殺死腳本,我們有機會在catch中處理它。

讓我們看一些例子。

一個無錯誤的示例:顯示(1)(2)

try {

  alert('開始運行try');  // (1) <--

  // ...這里無錯誤

  alert('結(jié)束運行try');   // (2) <--

} catch (err) {

  alert('catch被忽略,因為這里無錯誤'); // (3)

}

trying >>

帶有錯誤的示例:顯示(1)(3)

try {

  alert('開始運行try');  // (1) <--

  lalala; // 錯誤,變量未定義!

  alert('結(jié)束運行try(永遠不會到達)');  // (2)

} catch (err) {

  alert('出現(xiàn)錯誤!'); // (3) <--

}

trying >>

try...catch 僅適用于運行時錯誤

為了try...catch工作,代碼必須是可運行的。換句話說,它應(yīng)該是有效的JavaScript。

如果代碼在語法上是錯誤的,那么它將無法正常工作,例如,它具有不匹配的花括號:

try {
  {{{{{{{{{{{{
} catch (err) {
  alert("引擎不懂這個代碼,無效代碼");
}

trying >>

JavaScript引擎首先讀取代碼,然后運行它。在讀取階段發(fā)生的錯誤稱為“解析時”錯誤,并且無法恢復(fù)(從該代碼內(nèi)部),那是因為引擎無法理解代碼。

因此,try...catch只能處理有效代碼中發(fā)生的錯誤。這種錯誤稱為“運行時錯誤”,有時也稱為“異常”。

try...catch 同步工作

如果在“預(yù)定的”代碼中發(fā)生異常,例如在trysetTimeout,則try...catch不會捕獲到該異常:

try {
  setTimeout(function() {
    noSuchVariable; // 腳本在這里停止
  }, 1000);
} catch (err) {
  alert( "不會執(zhí)行" );
}

trying >>

這是因為函數(shù)本身是在引擎已離開try...catch構(gòu)造時稍后執(zhí)行的。

要在預(yù)定函數(shù)內(nèi)捕獲異常,try...catch必須在該函數(shù)內(nèi):

setTimeout(function() {
  try {
    noSuchVariable; // try...catch 處理這個錯誤!
  } catch {
    alert( "錯誤被捕獲!" );
  }
}, 1000);

trying >>

try...catch...finally

try...catch構(gòu)造可能還包含一個代碼子句:finally

如果存在,它將在所有情況下運行:

  • try之后,如果沒有錯誤,
  • catch之后,如果有錯誤。

擴展語法如下所示:

try {
   ... 嘗試執(zhí)行這里代碼 ...
} catch (err) {
   ... 處理錯誤 ...
} finally {
   ... 總是執(zhí)行 ...
}

 try...catch...finally執(zhí)行流程
try...catch...finally執(zhí)行流程

嘗試運行以下代碼:

try {
  alert( 'try' );
  if (confirm('出錯?')) BAD_CODE();
} catch (err) {
  alert( 'catch' );
} finally {
  alert( 'finally' );
}

trying >>

該代碼有兩種執(zhí)行方式:

  1. 如果你對“出錯?”回答“是”,則try -> catch -> finally。
  2. 如果您說“否”,則try -> finally。

finally 和 return

finally子句適用于try...catch的任何退出,這里包括一個顯式的return

在下面的示例中,有一個returnin try。在這種情況下,finally在控件返回外部代碼之前執(zhí)行。

function func() {

  try {
    return 1;

  } catch (err) {
    /* ... */
  } finally {
    alert( 'finally' );
  }
}

alert( func() ); // 首先執(zhí)行finally里的alert, 然后再執(zhí)行try

trying >>

try...finally

try...finally不帶catch子句的構(gòu)造也很有用。當(dāng)我們不想在這里處理錯誤時,我們可以應(yīng)用它,但是要確保我們啟動的過程已經(jīng)完成。

function func() {
  // 開始做一些需要完成的事情
  try {
    // ...
  } finally {
    // 即使全部死亡都完成那件事
  }
}

try...catch有無finally的區(qū)別

比較兩個代碼片段。

1、第一個用于finally執(zhí)行以下代碼try...catch

try {
   // 工作 工作
} catch (err) {
   // 處理錯誤
} finally {
   清洗工作空間
}

2、第二個片段把清洗空間放在try...catch的后面:

try {
   // 工作 工作
} catch (err) {
   // 處理錯誤
}

清洗工作空間

我們肯定需要在工作后進行清理,無論是否有錯誤都沒有關(guān)系。

兩個代碼片段是否相等?在這里使用finally是否有優(yōu)勢?下面兩個例子說明了使用finally的優(yōu)勢。

當(dāng)我們看一個函數(shù)內(nèi)部的代碼時,區(qū)別變得很明顯。

如果“跳出”,則try...catch的行為會有所不同。

例如,當(dāng)有一個returntry...catch內(nèi)部時,該finally在任何來自try...catch的出口工作,甚至是通過return聲明。catch將在執(zhí)行完finally代碼之后再執(zhí)行。

function f() {
  try {
    alert('開始');
    return "結(jié)果";
  } catch (err) {
    /// ...
  } finally {
    alert('清洗!');
  }
}

f(); // 清洗!

trying >>

又例如,當(dāng)函數(shù)內(nèi)有throw時:

function f() {
  try {
    alert('開始');
    throw new Error("一個錯誤");
  } catch (err) {
    // ...
    if("can't handle the error") {
      throw err;
    }

  } finally {
    alert('清洗!')
  }
}

f(); // 清洗!

trying >>

finally是保證在這里進行清理。如果僅將代碼放在的f()末尾,則在這些情況下將無法運行該代碼。

 

標(biāo)簽: try-catch  
相關(guān)文章
    x
    • 站長推薦
    /* 左側(cè)顯示文章內(nèi)容目錄 */