iT邦幫忙

2022 iThome 鐵人賽

DAY 4
0
Modern Web

前端蛇行撞牆記系列 第 4

Day4 前端蛇行撞牆記 - 讓你理解的 try...catch

  • 分享至 

  • xImage
  •  

前言

try...catch? 為何不用if...else就好了?

相信在開始學寫JS的初期都是if...else條件判斷用爽爽,然後突然有個學姊說可以試試看用try...catch,不會一直巢狀下去,而且還可以統一錯誤處理喔!

接著開始研究try...catch,可是覺得怎麼沒有一篇文章看得懂?太難了吧!

好的,我自首。以上是我剛學try...catch的小劇場 XD
可是在後來把try...catch學起來之後就覺得喔喔喔喔,好方便喔~就可以不用管這塊了耶!

現在看文章的人應該都還不太懂try...catch吧?
我來講講以前我看不懂的細節,讓過去的我看應該看得懂的文章

try...catch 錯誤及例外處理

try...catch 就是有一個try 區塊跟 catch 區塊,如果在try 區塊執行有錯誤或者例外情形的話就跳到catch 區塊去處理。

try {
    //要被執行的部分
} carch(error) {
    //要攔截錯誤的部分
}

錯誤是什麼意思? 在if...else的朋友,錯誤不是false的意思喔。

false是你們自己定義的false,而錯誤是會報錯的那種錯誤,例如我在try 區塊放了一個根本沒有的變數、函式,正常的node or 瀏覽器都會報錯對吧?但我們如果在try...catch裡面,就可以控制這個錯誤,不要讓他全部報錯。

來看看範例:
呼叫一個根本不知道哪裡來的hello(),他就會報錯,像這樣:

可是如果是在try區塊呼叫一個根本不知道哪裡來的hello()的話,一發現有錯就會直接跳到catch,然後印出錯誤訊息

try {
    hello()
} catch(error) {
    console.log(error.message)
}

錯誤訊息:

因為我們的錯誤處理就只是讓他console.log()印出東西而已。

但也是可以讓他紅紅的喔,改成console.error()就好了。

那,我可以像是if...else一樣自己定義我要的false嗎?
Of course you can!

接著我們就要講到catch的那個奇妙的參數了

catch(e)

try...catch那個catch為什麼有一個參數啊?
我們來看看MDN上的定義:

The catch-block specifies an identifier (e in the example above) that holds the value of the exception; this value is only available in the scope of the catch-block.

這個參數的值就是一個識別符的意思,你可以自己定義,要e or error as you like。

裡面的 error.message 就是可以去定義要報出什麼錯誤了,像上面我沒有定義,他就跑出「hello is not define」這種我們很常見到的句子,這就是當JS找到沒有被定義的函式會跑出來的錯誤提示。

現在來到正題了,定義錯誤or例外。

throw new Error("...")

throw new Error()就是丟出一個錯誤,先來看個範例我故意在try裡面就throw

可以看到程式根本不會運行到console.log("Hi")的部分,就到catch裡面了。
要在哪個地方丟錯誤就放throw new Error(),這邊就有點像是 else的部分。

現階段我會用到try...catch的時候是在驗證使用者輸入的數字的時候,會控制輸入的數字一定要是整數,這就是我定義的例外情形(expection)。

會寫一個function來驗證錯誤,裡面會用if判斷,但會用反向的方式去寫。

來看看我寫的驗證錯誤的範例:
意思是如果不是正整數,就丟出 "不是正整數啊!" 的提醒。

function checkIsInteger(number) {
  if (!Number.isInteger(number)) {
    throw new Error("不是正整數啊!");
  }
}

然後在主要的function裡面呼叫他:

function add(number1, number2) {
  try {
    checkIsInteger(number1);
    checkIsInteger(number2);

    const result = number1 + number2;

    return result;
  } catch (error) {
    console.log(error.message);
  }
}

// 故意傳一個不是正整數的
const result = add(0.5, 1);

console.log(result);

這個add function,要輸入兩個數字,而且都要通過 checkIsInteger的試煉之後才能繼續相加。

再看看驗證函式,裡面的throw new Error(" "),就是丟出一個錯誤物件,這個new Error就是JS提供給錯誤處理使用的。

意思是,在這裡符合 if 條件的時候創建了一個Error物件,參數「不是正整數」就帶進去變成錯誤物件的message。

function checkIsInteger(number) {
  if (!Number.isInteger(number)) {
    throw new Error("不是正整數啊!");
  }
}

所以這裡可以連到catch的 error.message,這時候我已經把這個function的錯誤物件準備好了,一發生錯誤就可以拿到錯誤物件裡的message訊息然後印出。

catch (error) {
    console.log(error.message);
  }

這樣就可以每個驗證都只要丟一個錯誤訊息就好,是不是程式看起來更簡潔美觀了?也不會發生if...else hell了!

try...catch...finally

其實try...catch還有第三個finally,finally這區塊就是不管怎麼都會去做的一個區塊。

而且try可以只配catch or finally喔,擇一也可以使用。

try {
    //要被執行的區塊
} carch(error) {
    //要攔截錯誤的區塊
} finally {
    //不管錯誤與否都會被執行的區塊
}

統整

  • try...catch可以使用在錯誤或是例外情形(expection),錯誤可能是亂呼叫不存在的變數or函式,但例外情形是可以自己定義的
  • throw new Error() 要放在try區塊裡面才會被catch接到
  • new Error() JS內建提供錯誤處理的物件,會連接到catch的error.message
  • try...catch...finally

好了,大家應該有比較懂try...catch了吧!建議看完我如此白話的文章可以接著看 MDN 會說得更清楚更深入喔!

如果文章有錯誤請throw new Error("打錯拉笨蛋!原因...")給我,謝謝拉!

明天見嚕~


參考資料:過度焦慮的 try-catch
認識 try…catch,處理錯誤
MDN 流程控制與例外處理
MDN try...catch


上一篇
Day3 前端蛇行撞牆記 - 深拷貝、淺拷貝
下一篇
Day5 前端蛇行撞牆記 - 你有聽過循序式容器 / 關聯式容器嗎?
系列文
前端蛇行撞牆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
南國安迪
iT邦新手 3 級 ‧ 2022-09-20 13:47:03

在if...else的朋友,錯誤不是false的意思喔。

不愧是奶奶,各種像在哄小孩

jadddxx iT邦新手 5 級 ‧ 2022-09-21 12:00:02 檢舉

= =

我要留言

立即登入留言