第17章 错误处理与调试
1. 浏览器报告的错误
2. 错误处理
(1) try-catch语句
try {
window.someNonexistentFunction();
} catch (error){
alert(error.message);
}
*finally 子句
只要代码中包含 finally 子句,则无论 try 或 catch 语句块中包
含什么代码——甚至 return 语句,都不会阻止 finally 子句的执行。
*错误类型
-
Error
是基类型,其他错误类型都继承自该类型。 -
EvalError 类型
的错误会在使用 eval()函数而发生异常时被抛出。 -
RangeError 类型
的错误会在数值超出相应范围时触发。 -
ReferenceError类型
找不到对象的情况下抛出。
5.syntaxError
,当我们把语法错误的 JavaScript 字符串传入 eval()函数时,就会导致此类错误。 -
TypeError 类型
在 JavaScript 中会经常用到,在变量中保存着意外的类型时,或者在访问不存在的 方法时,都会导致这种错误。错误的原因虽然多种多样,但归根结底还是由于在执行特定于类型的操作 时,变量的类型并不符合要求所致。
7.URIError
在使用 encodeURI()或 decodeURI(),而 URI 格式不正确时,就会导致 URIError 错误。
(2) 抛出错误
- 与 try-catch 语句相配的还有一个
throw 操作符
,用于随时抛出自定义错误。抛出错误时,必须要给 throw 操作符指定一个值,这个值是什么类型,没有要求。 - 在遇到 throw 操作符时,代码会立即停止执行。仅当有 try-catch 语句捕获到被抛出的值时,代 码才会继续执行
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.");
- 利用原型链还可以通过继承 Error 来创建
自定义错误类型
。
function CustomError(message){
this.name = "CustomError";
this.message = message;
}
CustomError.prototype = new Error();
throw new CustomError("My message");
*抛出错误的时机
应该在出现某 种特定的已知错误条件,导致函数无法正常执行时抛出错误。
function process(values){
if (!(values instanceof Array)){
throw new Error("process(): Argument must be an array.");
}
values.sort();
for (var i=0, len=values.length; i < len; i++){
if (values[i] > 100){
} return values[i];
}
return -1;
}
(3) 错误(error)事件
任何没有通过 try-catch 处理的错误都会触发 window 对象的 error 事件
。
1.在任何 Web 浏览器中,onerror 事件
处理程序都不会创建 event 对象
, 但它可以接收三个参数
:错误消息、错误所在的 URL 和行号。
2.要指定 onerror 事件处理程序,必须使用如下所示的DOM0 级技术
,它没有遵循“DOM2 级 事件”的标准格式。
- 在事件处理程序中返回 false,可以阻止浏览器报告错误的默认行为。
window.onerror = function(message, url, line){
alert(message);
return false;
};
- 图像也支持 error 事件。只要图像的 src 特性中的 URL 不能返回可以被识别的图像格式,就会触 发 error 事件。
var image = new Image();
EventUtil.addHandler(image, "load", function(event){
alert("Image loaded!");
});
EventUtil.addHandler(image, "error", function(event){
alert("Image not loaded!");
});
image.src = "smilex.gif"; //指定不存在的文件
(4) 处理错误的策略
(5) 常见的错误类型
*类型转换错误
类型转换错误
发生在使用某个操作符
,或者使用其他可能会自动转换值的数据类型的语言结构时。
在使用相等(==)和不相等(!=)操作符,或者在 if、for 及 while 等流控制语句中使用非布尔值时, 最常发生类型转换错误。
*数据类型错误
*通信错误
- 第一种通信错误与格式不正确的 URL 或发送的数据有关。最常见的问题是在将数据发送给服务器 之前,没有使用 encodeURIComponent()对数据进行编码。
(6) 区分致命错误和非致命错误
- 非致命错误:
- 不影响用户的主要任务;
- 只影响页面的一部分;
- 可以恢复;
- 重复相同操作可以消除错误。
- 致命错误:
- 应用程序根本无法继续运行;
- 错误明显影响到了用户的主要操作;
- 会导致其他连带错误。
(7) 把错误记录到服务器
3. 调试技术
(1) 将消息记录到控制台
- 通过
console 对象
向 JavaScript 控制台中写入消息,这个对象具有下列方法:
- error(message):将错误消息记录到控制台
- info(message):将信息性消息记录到控制台
- log(message):将一般消息记录到控制台
- warn(message):将警告消息记录到控制台
- 通过
opera.postError()方法
来访问。这个方法 接受一个参数,即要写入到控制台中的参数。 - 在 JavaScript 中运行 Java 代码。
function log(message){
if (typeof console == "object"){
console.log(message);
} else if (typeof opera == "object"){
opera.postError(message);
} else if (typeof java == "object" && typeof java.lang == "object"){
java.lang.System.out.println(message);
}
}
function sum(num1, num2){
log("Entering sum(), arguments are " + num1 + "," + num2);
log("Before calculation");
var result = num1 + num2;
log("After calculation");
log("Exiting sum()");
return result;
}
(2) 将消息记录到当前页面
在页面中开辟一小块区域,用以显示消息。这个区域通常是一个 元素,而该元素可以总是出现在页面中,但仅用于调试目的;也可以是一个根据需要动态创建的元素。
function log(message){
var console = document.getElementById("debuginfo");
if (console === null){
console = document.createElement("div");
console.id = "debuginfo";
console.style.background = "#dedede";
console.style.border = "1px solid silver";
console.style.padding = "5px";
console.style.width = "400px";
console.style.position = "absolute";
console.style.right = "0px";
console.style.top = "0px";
document.body.appendChild(console);
}
console.innerHTML += "" + message + "
";
}
(3) 抛出错误
对于大型应用程序来说,自定义的错误通常都使用
assert()函数
抛出。这个函数接受两个参数, 一个是求值结果应该为 true 的条件,另一个是条件为 false 时要抛出的错误。
function assert(condition, message){
if (!condition){
throw new Error(message);
}
}
function divide(num1, num2){
assert(typeof num1 == "number" && typeof num2 == "number",
"divide(): Both arguments must be numbers.");
return num1 / num2;
}
4.常见的 IE 错误
(1) 操作终止
操作终止
: 在修改尚未加载完成的页面时,就会发生操作终止错误。发生错误时, 会出现一个模态对话框,告诉你“操作终止。”单击确定(OK)按钮,则卸载整个页面,继而显示一张 空白屏幕。
当