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

贊助商

分類目錄

贊助商

最新文章

搜索

js:try...catch...finally捕獲錯(cuò)誤處理的用法實(shí)例

作者:admin    時(shí)間:2021-4-28 1:2:14    瀏覽:

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

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

 js: try-catch-finally捕獲錯(cuò)誤
js: try-catch-finally捕獲錯(cuò)誤

“ try…catch”語法

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

try {

  // 代碼...

} catch (err) {

  // 錯(cuò)誤處理

}

它是這樣的:

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

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

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

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

讓我們看一些例子。

一個(gè)無錯(cuò)誤的示例:顯示(1)(2)

try {

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

  // ...這里無錯(cuò)誤

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

} catch (err) {

  alert('catch被忽略,因?yàn)檫@里無錯(cuò)誤'); // (3)

}

trying >>

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

try {

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

  lalala; // 錯(cuò)誤,變量未定義!

  alert('結(jié)束運(yùn)行try(永遠(yuǎn)不會到達(dá))');  // (2)

} catch (err) {

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

}

trying >>

try...catch 僅適用于運(yùn)行時(shí)錯(cuò)誤

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

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

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

trying >>

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

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

try...catch 同步工作

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

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

trying >>

這是因?yàn)楹瘮?shù)本身是在引擎已離開try...catch構(gòu)造時(shí)稍后執(zhí)行的。

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

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

trying >>

try...catch...finally

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

如果存在,它將在所有情況下運(yùn)行:

  • try之后,如果沒有錯(cuò)誤,
  • catch之后,如果有錯(cuò)誤。

擴(kuò)展語法如下所示:

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

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

嘗試運(yùn)行以下代碼:

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

trying >>

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

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

finally 和 return

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

在下面的示例中,有一個(gè)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)我們不想在這里處理錯(cuò)誤時(shí),我們可以應(yīng)用它,但是要確保我們啟動的過程已經(jīng)完成。

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

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

比較兩個(gè)代碼片段。

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

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

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

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

清洗工作空間

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

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

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

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

例如,當(dāng)有一個(gè)returntry...catch內(nèi)部時(shí),該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時(shí):

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

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

f(); // 清洗!

trying >>

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

 

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