zoukankan      html  css  js  c++  java
  • JavaScript的错误处理

    2017-04-17 19:55 by 阿诚de窝, 29 阅读, 0 评论, 收藏编辑

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

    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代码执行停止了。

  • 相关阅读:
    [APM] OneAPM 云监控部署与试用体验
    Elastic Stack 安装
    xBIM 综合使用案例与 ASP.NET MVC 集成(一)
    JQuery DataTables Selected Row
    力导向图Demo
    WPF ViewModelLocator
    Syncfusion SfDataGrid 导出Excel
    HTML Table to Json
    .net core 2.0 虚拟目录下载 Android Apk 等文件
    在BootStrap的modal中使用Select2
  • 原文地址:https://www.cnblogs.com/lancidie/p/7345812.html
Copyright © 2011-2022 走看看