• HTML5学习笔记(二十六):JavaScript的错误处理


    错误相关的调试和处理在开发中是特别重要的一种技能。

    try-catch

    我们来看下面的情况:

    1 // noneFunc 这个方法并不存在
    2 window.noneFunc();
    3 // js 报错后终止运行这行代码并不会执行到
    4 console.log("hello");

    为了避免不继续执行后续代码的情况,可以对可能抛出错误的代码使用try-catch命令包围。

    1 try {
    2     // noneFunc 这个方法并不存在
    3     window.noneFunc();
    4 } catch (error) {
    5     // 一旦报错将会跳到这里执行
    6     console.log(error.message); // window.noneFunc is not a function
    7 }
    8 // 执行不中断,这句代码会得到执行
    9 console.log("hello");

    这里要注意error对象有多个属性,但是message属性是所有浏览器都支持的属性。

    finally

    在try-catch语句中,finally语句是可选语句,其作用是无论被try-catch包含的代码是否出现错误,都一定会执行finally语句包含的代码,如下:

     1 try {
     2     window.test();
     3 } catch (error) {
     4     console.log(error.message);
     5 } finally {
     6     console.log("finally code");
     7 }
     8 
     9 //window.test is not a function
    10 //finally code

    我们再看一下下面的代码:

     1 function test1() {
     2     try {
     3         return 0;
     4     } catch (error) {
     5         return 1;
     6     } finally {
     7         return 2;
     8     }
     9 }
    10 
    11 console.log(test1()); // 2
    12 
    13 function test2() {
    14     try {
    15         return 0;
    16     } catch (error) {
    17         return 1;
    18     }
    19 }
    20 
    21 console.log(test2()); // 0
    22 
    23 function test3() {
    24     try {
    25         // test 方法并不存在
    26         test();
    27         return 0;
    28     } catch (error) {
    29         return 1;
    30     } finally {
    31         return 2;
    32     }
    33 }
    34 
    35 console.log(test3()); // 2
    36 
    37 function test4() {
    38     try {
    39         // test 方法并不存在
    40         test();
    41         return 0;
    42     } catch (error) {
    43         return 1;
    44     }
    45 }
    46 
    47 console.log(test4()); // 1

    从上面的例子来看,在try-catch中包含的return语句都没有执行返回,只会执行finally里的return语句,再看下面的例子:

     1 function test() {
     2     try {
     3         return 0;
     4     } catch (error) {
     5         return 1;
     6     } finally {
     7         console.log("finally");
     8     }
     9 }
    10 
    11 console.log(test()); // 0

    如果finally中没有包含return语句,则先执行finally中的语句之后,在返回try-catch语句中的值,我们再看下面的例子:

     1 function test1() {
     2     var i = 0;
     3     try {
     4         return ++i;
     5     } catch (error) {
     6         return -1;
     7     } finally {
     8         return i;
     9     }
    10 }
    11 
    12 console.log(test1()); // 1
    13 
    14 function test2() {
    15     var i = 0;
    16     try {
    17         return i++;
    18     } catch (error) {
    19         return -1;
    20     } finally {
    21         return i;
    22     }
    23 }
    24 
    25 console.log(test2()); // 1

    我们发现尽管没有执行try-catch中的return语句,但是try-catch中的return语句仍然是执行了的,可以理解为如果finally中存在return关键字,则try-catch中的return关键字都被移除。

    还有一种情况,如下:

     1 function test1() {
     2     var i = 0;
     3     try {
     4         return 0;
     5     } catch (error) {
     6         return 1;
     7     } finally {
     8         if (i != 0) {
     9             return 2;
    10         }
    11     }
    12 }
    13 
    14 console.log(test1()); // 0
    15 
    16 function test2() {
    17     var i = 0;
    18     try {
    19         return 0;
    20     } catch (error) {
    21         return 1;
    22     } finally {
    23         if (i == 0) {
    24             return 2;
    25         }
    26     }
    27 }
    28 
    29 console.log(test2()); // 2

    我们还发现,如果由于条件判断等原因,导致finally中的return语句没有执行到,还是会返回try-catch中的return语句。

    错误处理

    在JavaScript中,有7种内置的错误类型:

    • Error:其它6个错误类型的基类,也提供给开发人员自己定义新的错误类型。
    • EvalError:执行eval()方法时的报错。
    • RangeError:数值超出范围是报错,如:new Array(-20)或new Array(Number.MAX_VALUE)。
    • ReferenceError:找不到对象时的报错。
    • SyntaxError:执行eval()方法语法错误时报错。
    • TypeError:类型错误时的报错,如:new 10或"name" in true时。
    • URIError:在调用encodeURI和decodeURI时出错的报错。

    对浏览器来说,只要try-catch包含的代码抛出错误,则浏览器认为该错误已经被处理了,我们需要自行处理该错误。

    抛出错误

    抛出错误使用throw关键字,对于抛出的错误类型则没有规定,可以是任意类型,而浏览器对用户抛出的错误处理也和内置的错误一致,如果没有try-catch进行包含的话,浏览器会暂停JS的执行。

    我们可以简单的抛出一个错误类型或自定义类型:

    1 throw {msg:"my error"};
    2 throw new Error("our error");

    我们可以继承Error类型,实现自己的错误类型:

     1 function MyError(msg, code) {
     2     this.message = msg;
     3     this.code = code;
     4 }
     5 
     6 MyError.prototype = new Error();
     7 
     8 try {
     9     throw new MyError("my error", 1001);
    10 } catch (error) {
    11     console.log(error.message + ", " + error.code); // my error, 1001
    12 }

    当然,建议对catch中的error对象使用instanceof关键字进行类型筛选再来有针对性的处理错误。

    error事件

    error事件仅支持DOM0级的监听方法,即不能通过addEventListener和removeEventListener方法来注册和移除,同时该方法也不会创建对应的event对象,而是将报错信息直接传递过来。

    可以理解error事件为整个页面的try-catch语句,如下:

     1 window.onerror = function (message, url, line) {
     2     console.log("message: " + message + ", url: " + url + ", line: " + line);
     3     // 返回 true 则浏览器不会打印错误信息到 console 控制台,返回 false 则浏览器会打印错误信息
     4     return true;
     5 };
     6 
     7 test();
     8 
     9 // 无论如何报错后的代码都不会再执行了
    10 console.log("run this code!");

    该事件可以用来在应用开发时收集浏览器中没有被try-catch包围的语句抛出的错误,但实际上在发布给用户的程序中,是不应该存在这样的错误,因为error事件一旦抛出就表示JS代码执行停止了。

  • 相关阅读:
    快捷定位目录 z武器
    [UOJ317]【NOI2017】游戏 题解
    2-SAT 问题与解法小结
    link-cut-tree 简单介绍
    hihocoder #1456 : Rikka with Lattice(杜教筛)
    杜教筛小结
    BZOJ 2969: 矩形粉刷(期望)
    UVA10294 Arif in Dhaka (群论,Polya定理)
    BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案)
    BZOJ 2683: 简单题(CDQ分治 + 树状数组)
  • 原文地址:https://www.cnblogs.com/hammerc/p/6435355.html
Copyright © 2020-2023  润新知