JavaScript 異常處理

雲崖先生發表於2020-08-13

程式異常

  程式異常可分為邏輯異常和語法異常,對於初學者而言語法異常居多,隨著不斷的學習對語言越來越熟悉後語法異常減少邏輯異常增多。

  在JavaScript中提供了對異常進行處理的語句,在適當的時候使用它們能夠使程式變得更加健壯。

  但是要注意不要濫用異常處理,它會使程式的可讀性變差。

異常物件

  所有的異常都是物件

異常型別

  在JavaScript中,常見異常型別有以下幾種。

異常型別簡述
Error Error是最基本的錯誤型別,其他的錯誤型別都繼承自該型別。因此,所有錯誤的型別共享了一組相同的屬性。 這個型別的錯誤很少見。一般使用開發人員自定義丟擲的錯誤
EvalError 這個錯誤會在使用eval()函式發生異常時候丟擲。兩種情況會出錯:1.使用new來進行例項化 2.嘗試為變數起名為eval,因為它是一個關鍵字,所以這是不被允許的
RangeError 數值超出範圍,常見於Array操作中
ReferenceError 變數找不到
SyntaxError 語法錯誤
TypeError 型別錯誤
URIError 在使用encodeURI或者decodeURI因為URL格式不正確時,就會導致URIError錯誤。

異常捕獲

try catch

  使用trycatch語句進行捕獲異常。

  try用於檢測可能出現異常的程式碼塊

  catch用於處理捕捉到的異常,可指定引數獲取異常資訊

  try...catch 語句有一個包含一條或者多條語句的try程式碼塊,0個或1個的catch程式碼塊,catch程式碼塊中的語句會在try程式碼塊中丟擲異常時執行。

  如果try程式碼塊中的語句(或者try 程式碼塊中呼叫的方法)一旦丟擲了異常,那麼執行流程會立即進入catch 程式碼塊。

  如果try程式碼塊沒有丟擲異常,catch程式碼塊就會被跳過。

<script>

        "use strict";

        try {
                console.log(username);
        } catch (e) {  // 會捕獲異常的所有資訊
                console.log("處理了一個異常:", e);
        }

/*

處理了一個異常: ReferenceError: username is not defined
    at 1.html:56

*/

</script>

finally

  finally塊包含了在trycatch塊完成後、下面接著try...catch的語句之前執行的語句。

  finally塊無論是否丟擲異常都會執行。如果丟擲了一個異常,就算沒有異常處理,finally塊裡的語句也會執行。

<script>

        "use strict";

        try {
                console.log(username);
        } catch (e) {  // 會捕獲異常的所有資訊
                console.log("處理了一個異常,ID:", e);
        } finally {
                console.log("無論有沒有異常都會執行我");
        }


</script>

主動異常

throw

  在某些時候我們需要主動丟擲異常,使用throw語句丟擲異常。

<script>

        "use strict";

        throw new Error("這是一個錯誤")

</script>

表示式形式

  你可以丟擲任意表示式而不是特定一種型別的表示式。下面的程式碼丟擲了幾個不同型別的表示式:

<script>

        "use strict";

        throw "Error2";   // String type  
        throw 42;         // Number type
        throw true;       // Boolean type
        throw { toString: function () { return "I'm an object!"; } };

</script>

自定義異常

  繼承Error原型物件,可配置自定義的異常。

  Error建構函式具有message可選引數,用於顯示人類可閱讀的錯誤描述資訊

函式形式

<script>

        "use strict";

        function MyError(message) {
                this.name = 'MyError';
                this.message = message || 'Default Message';
                this.stack = (new Error()).stack;
        }

        Object.setPrototypeOf(MyError, Error);  // 繼承Error原型物件

        try {
                throw new MyError();
        } catch (e) {
                console.log(e.name);  // MyError
                console.log(e.message);  // Default Message
        }


        try {
                throw new MyError("自定義異常被丟擲");
        } catch (e) {
                console.log(e.name);  // MyError
                console.log(e.message);  // 自定義異常被丟擲
        }

</script>

類形式

<script>

        "use strict";

        class MyError extends Error {
                constructor(message) {
                        super();
                        this.name = "MyError";
                        this.message = message || 'Default Message';
                        this.stack = (new Error()).stack;
                }
        }

        try {
                throw new MyError();
        } catch (e) {
                console.log(e.name);  // MyError
                console.log(e.message);  // Default Message
        }


        try {
                throw new MyError("自定義異常被丟擲");
        } catch (e) {
                console.log(e.name);  // MyError
                console.log(e.message);  // 自定義異常被丟擲
        }

</script>