js 在拋出錯誤的時候會使用到 throw

提到throw之前要先來介紹一下相同性質的try, catch

try…catch

它會分成兩個區塊,一個 try 一個 catch

1
2
3
4
5
6
try {
// 要執行的程式
} catch(error) {
// ...
// 錯誤發生時,上面的就不會執行,改執行這邊
}

舉例時間:

1
2
3
4
5
try {
console.apple("apple不是正確的使用方式喔");
} catch (e) {
console.log("我錯了");
}

這段 code 的結果會印出我錯了,如下:

為什麼會發生這樣的結果?這是因為如果try區塊裡面的程式碼假如沒有任何的錯誤,就會直接忽略掉catch區塊裡面的程式碼,反之有錯的話,就會以catch裡面的程式碼為主,而錯誤的try就會中斷執行,所以在這個範例來說,因為try寫錯了,所以會以try裡面的程式碼為主

另外如果catch區塊如果接受了一個參數,就可以直接利用這個參數獲取錯誤資料,一般都會是直接在後台輸出資料,這邊來試試看:

1
2
3
4
5
try {
console.apple("apple不是正確的使用方式喔");
} catch (e) {
console.log("錯誤訊息 :", e);
}

這段 code 的結果會印出錯誤資訊,如下:

throw

接下來介紹這次的主題throw,它常常用於上面提到的try…catch結構,throw這個語句只要一出現就會直接中斷程式執行,代表說在它之後的語句都不會再被執行,簡單來說,在try的區塊時碰到throw就會直接中斷執行並且把控制權交給catch的區塊,所以說要是沒有catch的區塊,程式就會立刻停止

就如同最前面說的,throw可以拋出一個錯誤,這樣的好處是可以很清楚的知道說錯誤的具體位置,可以很方便去做判斷

舉例時間:

1
2
3
4
5
6
7
8
9
10
11
try {
console.log("這邊很多蘋果,準備開始賣給顧客!");
throw "等等有壞蘋果!終止交易!"; // throw 會中斷進行
// 故意製造壞蘋果
console.BadApple("壞蘋果x5");
// 假如沒有被中斷,可以正常賣蘋果的世界線
console.log("好吃蘋果,大賣特賣,大家快來買!");
} catch (e) {
console.log(e);
console.log("有壞蘋果不准你賣!");
}

這段 code 的結果順序會是

1
2
3
1. 這邊很多蘋果,準備開始賣給顧客!
2. 等等有壞蘋果!終止交易!
3. 有壞蘋果不准你賣!

如下:

首先,因為throw會中斷後面所有語句執行的特性,所以上面那段範例中還沒遇到壞蘋果x5就會直接跳到catch區塊的有壞蘋果不准你賣!,這邊我故意把壞蘋果x5弄成製造錯誤的方式,但是一樣被中斷跳過,於是可以發現一件事情:

throw中斷了後面所有語句,包括了錯誤也一樣

所以這邊衍伸出了一個問題,如果錯誤是發生在throw語句之前,那會發生什麼事情呢,我們來試試看:

1
2
3
4
5
6
7
8
9
10
try {
console.log("這邊很多蘋果,準備開始賣給顧客!");
console.BadApple("壞蘋果x5");
throw "等等有壞蘋果!終止交易!";
console.log("好吃蘋果,大賣特賣,大家快來買!");
} catch (e) {
console.log(e);
console.log("有壞蘋果不准你賣!");
}

結果如下:

從結果可以發現說,假如錯誤發生在throw語句之前,那麼錯誤還是會被正常的顯示出來,而throw語句傳送的東西就不會出現,所以就可以利用像是這種模式,慢慢的交替把程式碼錯誤的位置給尋找出來


以上是我在學習throw時研究的紀錄,有任何問題都歡迎指教~

參考資料

  1. MDN try…catch
  2. MDN 流程控制與例外處理