js高程读书笔记 第17章 错误处理与调试

[TOC]

本章内容

  • 理解浏览器报告的错误
  • 处理错误
  • 调试JavaScript代码

    错误处理

    try-catch语句

    1
    2
    3
    4
    5
    try{
    //可能会导致错误的代码
    } catch(error) {
    //在错误发生时怎么处理
    }

catch块会接收到一个而包含错误信息的对象,即使不想使用这个错误对象,也要给它起名字。这个对象中包含的实际信息会因浏览器而异,共同点是有一个保存着错误消息的message属性。

ECMA-262规定了这个错误类型的name属性。

1
2
3
4
5
try{
window.someNonexistentFunction();
} catch(e) {
console.log(e.message);
}
  1. finally子句
    finally子句一经使用,其代码无论如何都会执行。

  2. 错误类型

  • Error
  • EvalError
  • RangeError
  • ReferenceError
  • SyntaxError
  • TypeError
  • URIError

抛出错误

throw操作符,用于随时抛出自定义错误。

在遇到throw操作符时,代码会立即停止执行。仅当有try-catch语句捕获到被抛出的值时,代码才会继续执行。

在创建自定义错误消息时最常用的错误类型是Error、RangeEroor、ReferenceError和TypeError。

此时,需要为新创建的错误类型指定name和message属性。

1
2
3
4
5
6
7
8
function CustomError(message){
this.name = "CustomError";
this.message = message;
}

CustomError.prototype = new Error();

throw new CustomError("My message");

错误事件

任何没有通过try-catch处理的错误都会出发window对象的error事件。onerror事件处理程序可以接受三个参数:错误消息、错误所在的URL和行号。

图像也支持error事件。只要图像的src特性中的URL不能返回可以被识别的图像格式,就会触发error事件。

1
2
3
4
5
6
7
8
var image= new Image();
EventUtil.addHandler(image, "load", function(event){//addEventListener
alert("Image loaded!");
});
EventUtil.addHandler(image, "error", function(event){
alert("Image not loaded!");
});
image.src = "smilex.gif";//指定不存在的文件。

常见的错误类型

  • 类型转换错误
  • 数据类型错误
  • 通信错误

关于数据类型错误,大体上来说,基本类型的值应该使用typeof来洁厕,而对象的值应该使用instanceof来检测。

通信错误一般会出现在Ajax编程中,URL通信调用encodeURIComponent()对象对数据进行编码。

区分致命错误和非致命错误

对于致命错误,例如

1
2
3
4
5
6
7
8
9
10
11
for (var i = 0, len = mods.length; i < len; i++){
mods[i].init();//可能会导致致命错误
}
//下列代码可以将所有模块的错误编程非致命的
for (var i = 0, len = mods.length; i < len; i++){
try {
mods[i].init();
} catch(e) {
//在这处理错误
}
}

把错误记录到服务器

1
2
3
4
function logError(sev, msg){
var img = new Image();
img.src = "log.php?sev=" + encodeURIComponent(sev) + "&msg=" + encodeURIComponent(msg);
}

这里使用了Image对象来发送请求,这样做非常灵活

  • 所有浏览器都支持Image对象,包括哪些不支持XMLHttpRequest对象的浏览器。
  • 可以避免跨域限制。
  • 在记录错误的过程中出问题的概率比较低。
1
2
3
4
5
6
7
for(var i = 0, len = mods.length; i < len ; i++) {
try{
mods[i].init();
} catch(e) {
logError("nonfatal", "Module init failed: " + e.message);
}
}

调试技术

将消息记录到控制台

通过console对象向JavaScript控制台写入信息。

  • error
  • info
  • log
  • warn

将消息记录到当前页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function log(message){
var console = document.getElementById("debuginfo");
if(consile ===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 += "<p>" + message + "</p>";
}

抛出错误

1
2
3
4
5
function assert(condition, message) {
if (!condition) {
throw new Error(message);
}
}

常见的IE错误

操作终止 operation aborted

未知运行时错误

span标签不能包含div之类的块级元素

小结

  • 在可能发生错误的地方使用try-catch语句,这样有机会以适当的方式对错误给出响应。
  • 使用window.onerror事件处理程序,这种方式可以接受try-catch不能处理的所有错误