何米酥`s Blog

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

September 02, 2017

本章内容

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

错误处理

try-catch语句

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

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

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

try{
    window.someNonexistentFunction();
} catch(e) {
    console.log(e.message);
}
  1. finally子句

finally子句一经使用,其代码无论如何都会执行。

  1. 错误类型
  • Error
  • EvalError
  • RangeError
  • ReferenceError
  • SyntaxError
  • TypeError
  • URIError

抛出错误

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

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

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

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

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事件。

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()对象对数据进行编码。

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

对于致命错误,例如

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) {
        //在这处理错误
    }
}

把错误记录到服务器

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

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

  • 所有浏览器都支持Image对象,包括哪些不支持XMLHttpRequest对象的浏览器。
  • 可以避免跨域限制。
  • 在记录错误的过程中出问题的概率比较低。
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

将消息记录到当前页面

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>";
}

抛出错误

function assert(condition, message) {
    if (!condition) {
        throw new Error(message);
    }
}

常见的IE错误

操作终止 operation aborted

未知运行时错误

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

小结

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

Profile picture

Written by 何坤舆 EFE