JavaScript 異常處理

程序異常

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

  在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>