第17章 错误处理与调试
1.避免浏览器响应 JavaScript 错误的方法:
- 在可能发生错误的地方使用 try-catch 语句
- 使用 window.onerror 事件处理程序,这种方式可以接受 try-catch 不能处理的所有错误(仅限于 IE、Firefox 和 Chrome)。
2.try-catch 语句, JavaScript 中处理异常的一种标准方式。把所有可能会抛出错误的代码都放在 try 语句块中,而把那些用于错误处理的代码放在 catch 块中。如果 try 块中的任何代码发生了错误,就会立即退出代码执行过程,然后接着执行 catch 块。此 时,catch 块会接收到一个包含错误信息的对象,该对象有一个保存着错误消息的 message 属性和一个保存错误类型的 name 属性。(最适合处理那些我们无法控制的错误。)
try {
window.someNonexistentFunction();
} catch (error){
alert(error.message);
}
4.只要try-catch 语句代码中包含 finally 子句,则无论 try 或 catch 语句块中包含什么代码——甚至 return 语句,都不会阻止 finally 子句的执行。
//调用这个函数只能返回 0
function testFinally(){
try {
return 2;
} catch (error){
return 1;
} finally {
return 0;
}
}
5.7种错误类型:
- Error:基类型,其他错误类型都继承自该类型,主要目的是供开发人员抛出自定义错误。
- EvalError:在使用 eval()函数而发生异常时被抛出。(没有把 eval()当成函数调用)
- RangeError :在数值超出相应范围时触发。
- ReferenceError:在找不到对象的情况下触发。(通常,在访问不存在的变量时,就会发生)
- SyntaxError:把语法错误的 JavaScript 字符串传入 eval()函数是触发。
- TypeError:在执行特定于类型的操作 时,变量的类型并不符合要求所致。
- URIError:在使用 encodeURI()或 decodeURI(),而 URI 格式不正确时,导致错误。
在跨浏览器编程中,检查错误类型是确定处理方式的最简便途径,使用instanceof 操作符确定错误的类型。
try {
someFunction();
} catch (error){
if (error instanceof TypeError){
//处理类型错误
} else if (error instanceof ReferenceError){
//处理引用错误
} else {
//处理其他类型的错误
}
}
6.与 try-catch 语句相配的还有一个 throw 操作符,用于随时抛出自定义错误,抛出错误时,必须要给 throw 操作符指定一个值。在遇到 throw 操作符时,代码会立即停止执行。仅当有 try-catch 语句捕获到被抛出的值时,代码才会继续执行。通过使用某种内置错误类型,可以更真实地模拟浏览器错误。
//最常用的错误类型是 Error、RangeError、ReferenceError 和 TypeError
throw new Error("Something bad happened.");
throw new SyntaxError("I don’t like your syntax.");
throw new TypeError("What type of variable do you take me for?");
throw new RangeError("Sorry, you just don’t have the range.");
throw new EvalError("That doesn’t evaluate.");
throw new URIError("Uri, is that you?");
throw new ReferenceError("You didn’t cite your references properly.");
try-catch捕获错误的目的在于避免浏览器以默认方式处理它们;而throw抛出错误的目的在于提供错误发生具体原因的消息。
7.任何没有通过 try-catch 处理的错误都会触发 window 对象的 error 事件,onerror 事件处理程序不会创建 event 对象,接收三个参数:错误消息(一般只有错误消息有用)、错误所在的 URL 和行号。要指定 onerror 事件处理程序,必须使用DOM0 级技术。只要发生错误,无论是不是浏览器生成的,都会触发 error 事件,并执行事件处理程序。然后,浏览器默认的机制发挥作用,像往常一样显示出错误消息。像下面这样在事件处理程序中返回 false,可以阻止浏览器报告错误的默认行为。
window.onerror = function(message, url, line){
alert(message);
return false;
};
8.常见的三种错误:
- 类型转换错误:发生在使用某个操作符,或者使用其他可能会自动转换值的数据类型的语言结构时(比如==和!=执行比较之前会先转换不同类型的值;if 之类的流控制语句在确定下一步操作之前, 会自动把任何值转换成布尔值)
- 数据类型错误:未充分检测数据类型(可以对传入函数的参数进行检验,基本类型的值使用 typeof 来检测,对象的值使用 instanceof 来检测。)
- 通信错误:JavaScript 与服务器之间的任何一次通信,都有可能会产生错误。第一种通信错误与格式不正确的 URL 或发送的数据有关,最常见的问题是在将数据发送给服务器之前,没有使用 encodeURIComponent()对数据进行编码。第二种在服务器响应的数据不正确时,也会发生通信错误。
9.非致命错误:没有必要对用户给出提示
- 不影响用户的主要任务
- 只影响页面的一部分
- 可以恢复
- 重复相同操作可以消除错误
致命错误:必须通知用户
- 应用程序根本无法继续运行;
- 错误明显影响到了用户的主要操作;
- 会导致其他连带错误。
10.集中保存错误日志,以便查找重要错误的原因,把 JavaScript 错误也回写到服务器。首先需要在服务器上创建一个页面(或者一个服务器入口点),用于处理错误数据。这个页面的作用是从查询字符串中取得数据,然后再将数据写入错误日志中。这个页面可能会使用如下所示的函数:(记录到服务器中的错误 消息应该尽可能多地带有上下文信息,以便鉴别导致错误的真正原因)
//接收两个参数:表示严重程度的数值或字符串(视所用系统而异)及错误消息。
function logError(sev, msg){
var img = new Image();
img.src = "log.php?sev=" + encodeURIComponent(sev) + "&msg=" +
encodeURIComponent(msg);
}
使用了 Image 对象来发送请求,这样做非常灵活,主要表现如下几方面:
- 所有浏览器都支持 Image 对象,包括那些不支持 XMLHttpRequest 对象的浏览器。
- 可以避免跨域限制。通常都是一台服务器要负责处理多台服务器的错误,而这种情况下使用XMLHttpRequest 是不行的。
- 在记录错误的过程中出问题的概率比较低。大多数 Ajax 通信都是由 JavaScript 库提供的包装函数来处理的,如果库代码本身有问题,而你还在依赖该库记录错误,可想而知,错误消息是不可能得到记录的。
for (var i=0, len=mods.length; i < len; i++){
try {
mods[i].init();
} catch (ex){
logError("nonfatal", "Module init failed: " + ex.message);
} }
11.通过 console 对象向 JavaScript 控制台中写入消息,这个对象具有下列方法:
- error(message):将错误消息记录到控制台
- info(message):将信息性消息记录到控制台
- log(message):将一般消息记录到控制台
- warn(message):将警告消息记录到控制台
12.对于大型应用程序来说,自定义的错误通常都使用 assert()函数抛出。这个函数接受两个参数, 一个是求值结果应该为 true 的条件,另一个是条件为 false 时要抛出的错误。
function assert(condition, message){
if (!condition){
throw new Error(message);
}
}
13.常见的 IE 错误:
- 操作终止:修改尚未加载完成的页面时,就会发生操作终止错误。
- 无效字符:JavaScript 文件中存在无效字符时,IE 会抛出无效字符。
- 未找到成员:IE 中的所有 DOM 对象都是以 COM 对象形式实现的,会导致一些与垃圾收集相关的非常奇怪的行为,比如垃圾收集例程配合错误,造成未找到成员错误。
- 未知运行时错误:当使用 innerHTML 或 outerHTML 以下列方式指定 HTML 时,就会发生未知运行时错误:一是把块元素插入到行内元素时,二是访问表格任意部分(<table>、<tbody>等)的任意属性时。
- 语法错误:在服务器端组件动态生成 JavaScript 的情况下,比较容易出现这种错误。
- 系统无法找到指定资源:在使用 JavaScript 请求某个资源 URL,而该 URL 的长度超过了 IE 对 URL 10 最长不能超过 2083 个字符的限制时,就会发生这个错误。