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

时间: 2024-11-07 22:21:20

HTML5学习笔记(二十六):JavaScript的错误处理的相关文章

【Unity 3D】学习笔记二十六:unity游戏脚本(六)

在3D游戏世界中,任何一个游戏对象在创建的时候都会附带Transform(变换)组件,并且该组件是无法删除的,也不应该删除.在unity中,Transform面板一共有3个属性: Position  (位置) Rotation(旋转) Scale(缩放) 这三个值都是用来调整游戏对象在游戏界面中的位置,状态等相关参数. Position  (位置) 任何一个游戏对象的三维坐标都保存在Vector3容器中,该容器记录对象在X轴,Y轴,Z轴的坐标.一旦Vector33容器中的坐标发生变化,那么Sce

angular学习笔记(二十六)-$http(4)-设置请求超时

本篇主要讲解$http(config)的config中的timeout项: $http({ timeout: number }) 数值,从发出请求开始计算,等待的毫秒数,超过这个数还没有响应,则返回错误 demo: html: <!DOCTYPE html> <html ng-app = 'HttpGet'> <head> <title>18.4 $http(2)</title> <meta charset="utf-8"

马哥学习笔记二十六——MySQL主从复制

配置MySQL复制基本步骤: 一.master 1.启用二进制日志 log-bin = master-bin log-bin-index = master-bin.index 2.选择一个惟一server-id server-id = {0-2^32} 3.创建具有复制权限的用户 REPLICATION SLAVE REPLICATION CLIENT 二.slave 1.启用中继日志 relay-log = relay-log relay-log-index = 2.选择一个惟一的server

Java基础学习笔记二十六 JDBC

什么是JDBC JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库.原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句. JDBC原理 早期SUN公司的天才们想编写一套可以连接天下所有数据库的API,但是当他们刚刚开始时就发现这是不可完成的任务,因为各个厂商的数据库服务器差异太大了.后来SUN开始与数据库厂商们讨论,最终得出的结论是,由SUN提供一套访问数据库的规范(就是

Android学习笔记二十六.跨进程调用Service(AIDL Service)

跨进程调用Service(AIDL Service) 一.AIDL Service 1.什么是AIDL Service? AIDL,即Android Interface Definition Language.是Android用于定义远程接口,AIDL接口定义语言的语法比较简单,这种接口定义语言并不是真正的编程语言,它只是定义两个进程之间的通信接口.AIDL的语法与Java接口很相似,但存在如下几点差异: (1)AIDL定义接口的源代码必须以.aidl结尾; (2)AIDL接口中用到数据类型,除

学习笔记二十六:事件处理(二)

在这个并非尽善尽美的世界上,勤奋会得到报偿,而游手好闲则要受到惩罚.--毛姆 本讲内容:MouseEvent .MouseMotionListener 一.MouseEvent   让鼠标能知道鼠标按下的消息.知道点击的位置等五个方法. MouseMotionListener鼠标拖动坐标.鼠标移动坐标二个方法. public class Text extends JFrame { MyPanel mb=null; public static void main(String[] args) {

PHP学习笔记二十六【类的重载】

<?php //重载: //函数名一样,通过函数的参数个数或者是参数类型不同,达到调用同一个函数名 Class A{ // public function test1(){ // echo "test1()"; // } // public function test1($name) // { // echo "hello world"; // } //PHP不支持以上的重载方式 public function test1(){ echo "调用te

Linux学习笔记&lt;二十六&gt;——DNS服务器

DNS(Domain Name System 域名系统):提供Internet上域名到IP地址的映射 域名:又叫主机名,FQDN(Full Qualified Domain Name完全限定域名) 基本信息: Linux中通常使用bind服务来提供DNS服务器 应用层协议 基于UDP53端口号:用于查询 基于TCP53端口号:用于主从服务器同步数据 基于TCP953端口号:rndc用于远程控制DNS服务器 解析方式: 正向:FQDN <--> IP 反向:IP <-->FQDN 解

《Javascript权威指南》学习笔记之十六:BOM之源---BOM基本应用

BOM的基本应用包括:管理浏览器历史.解析地址和获取浏览器信息,本文将介绍这些应用. 一.浏览历史管理 1.history对象的方法和属性 History 对象包含用户(在浏览器窗口中)访问过的 URL,是 window 对象的一部分,可通过 window.history 属性对其进行访问.没有应用于 History 对象的公开标准,不过所有浏览器都支持该对象. length属性:返回浏览器历史列表中的URl数量.是"前进"和"后退"两个按钮之下包含的地址数的总和.

Android学习笔记二十五之ListView多布局实现

Android学习笔记二十五之ListView多布局实现 这一节是介绍ListView这个控件的最后一节,实现一个Item的多布局.像我们经常在用的各种即时通讯工具,QQ.微信等,假设他们的会话界面是ListView实现的,那么ListView就有多种Item布局,这一节,我们就来实现一个ListView的多种Item. 要实现ListView里面有多种Item,就要重写适配器的两个方法getViewTypeCount()和getItemViewType(int position),第一个方法是