JavaScript 错误处理与调试——“错误处理”的注重要点

try-catch语句

该语句最适合处置惩罚那些我们无法掌握的毛病,在明明白白地晓得本身的代码会发作毛病时,再运用该语句就不太适宜了。

ECMA-262第3版引入了try-catch语句,基础的语法以下所示:

try {
    // statements
} catch(e) {
    // statements
    console.log(e);
}

纵然不运用这个毛病对象,也要起个名字,对象中包括的现实信息因浏览器而异,但配合的是一个保留毛病音讯的

  • message属性,ECMA-262还划定了一个保留毛病范例的

  • name属性

一切浏览器都支撑这个属性(Opera 9之前的版本除外)。

try {
    document.getElementByIfd("fdsa");
} catch(e) {
    // statements
    console.log(e.message); //document.getElementByIfd is not a function
    console.log(e.name); //TypeError
}

又如:

try {
    var x = 1;
    var y = 0;
    console.log(z);
} catch(e) {
    // statements
    console.log(e.message); //z is not defined
    console.log(e.name); //ReferenceError
}

finally子句

虽然在try-catch块中是可选的,但finally子句一经用,不管如何都邑实行,以至return语句都不会阻挠,比方:

function test() {
    try {
        return 1;
    } catch (error) {
        return 2;
    } finally {
        return 3;
    }
}

上述代码返回3,当try中代码一般实行,finally会实行;当try中代码涌现毛病,catch代码会实行,finally代码也会实行。

毛病范例

每种毛病都有对应的毛病范例,而当毛病发作时,就会抛出响应范例的毛病对象,ECMA-262定义了7种毛病范例:

* `Error`: 基范例。
* `EvalError`: 运用eval()函数发作非常时抛出。
* `RangeError`: 数值超越响应局限时抛出。
* `ReferenceError`: 找不到对象时抛出。
* `SyntaxError`: 运用eval()函数中的字符串有语法毛病时抛出。
* `TypeError`: 在变量中保留不测范例或接见不存在的要领时抛出。
* `URIError`: 运用encodeURI或decodeURI()中URI花样不正确时抛出。

抛出毛病

与try-catch相配的另有一个

  • throw操作符,用于抛出自定义毛病。

抛出毛病时,必需给throw操作符指定一个值,这个值的范例没有请求,比方:

throw 123;
throw "Hello World!";

在碰到throw操作符时,代码会马上住手实行。

经由过程运用某种内置毛病范例,能够更实在

如:

try {
    throw new Error("nooo");
} catch (e) {
    console.log(e.message); //nooo
    console.log(e.name); //Error
}

或:

throw new SyntaxError("wwwwtttttfffff");

也能够建立自定义毛病范例:

function CustomError (message) {
    this.name = "CustomError";
    this.message = message;
}
CustomError.prototype = new Error();
var somebug = new CustomError("wtf");

try {
    throw somebug
} catch(e) {
    console.log(e.name); //CustomError
    console.log(e.message); //wtf
}

捕捉毛病的目标在于防止浏览器以默许体式格局处置惩罚它们;而抛出毛病的目标在于供应毛病发作详细缘由的音讯。

毛病(error)事宜

没有经由过程try-catch处置惩罚的毛病都邑触发window对象的

  • error事宜。任何浏览器中,onerror事宜处置惩罚顺序都不会建立event对象,但它能够接收3个参数:毛病音讯、毛病地点的URL和行号。

只需发作毛病,不管是否是浏览器天生的,都邑触发error事宜,并实行这个事宜处置惩罚顺序,假如在事宜处置惩罚顺序中返回false,能够阻挠浏览器报告毛病的默许行动,比方:

throw new Error("hello there");
window.onerror = function() {
    console.log(message); //Uncaught Error: hello there
    return false;
}

图象也支撑error事宜,只需图象的src属性中的URL不能返回能够被辨认的图象花样,就会触发error事宜。

var x = new Image();
x.onerror = function () {
    console.log("message"); //message
};
x.src = "fds.png";

罕见的毛病范例

罕见的三种毛病范例为:

  • 范例转换毛病

  • 数据范例毛病

  • 通讯毛病

范例转换毛病

范例转换毛病常发作在运用某个操作符或许自动转换数据范例的场景

第一种罕见毛病是运用相称和不等操作符

console.log(1 == "1"); //true
console.log(1 == true); //true

革新: 引荐运用全等( === ) 和非全等( !== ) 操作符, 来防止发作由于运用相称和不等操作符时激发的范例转换毛病;

console.log(1 === "1"); //false
console.log(1 === true); //false

第二种罕见毛病是在流掌握语句中运用非布尔值.

function concat(str1, str2) {
    if (str2) {
        return str1 + str2;
    } else {
        return str1;
    }
}
concat('a', 0); //a"
concat('a', 1); //"a1"

该要领的目标是当第二个参数存在的时刻返回两个字符串拼接效果;

当第二个参数不存在的时刻直接返回第一个参数.但是除了undefined会转换为布尔值false外, 0 也会转换为false, 而1则转换为true.因而挪用效果与本意不太一致.

革新:

function concat(str1, str2) {
    if (typeof str2 == "string") {
        return str1 + str2;
    } else {
        return str1;
    }
}
concat('a', 0); //a"
concat('a', 1); //"a"

数据范例毛病

在JavaScript中, 运用变量和函数参数之前是不会自动举行范例磨练的.因而须要开发人员本身编写数据范例检测的代码.比方:

function reverseSort(values) {
    if (values) { //这里的推断不能保证是数组范例
        values.sort();
        values.reverse();
    }

    console.log(values);
}
reverseSort("a"); //TypeError

这里假如传入的参数不是数组范例, 就会发作数据范例毛病.一般来说, 关于基础范例运用typeof举行范例磨练, 关于对象范例运用instanceof举行范例磨练.

function reverseSort(values) {
    if (values instanceof Array) {
        values.sort();
        values.reverse();
    }
    console.log(values);
}
reverseSort("a"); //a"
reverseSort([6, 2, 3, 8, 1, 5]); //[8, 6, 5, 3, 2, 1]

通讯毛病

场景一是在将数据发送给服务器之前, 未运用encodeURIComponent() 对数据举行编码.比方:

www.cnblogs.com ? backurl = http : //www.cnblogs.com?a=1

解决要领是运用encodeURIComponent() 对backurl背面的参数举行编码, 效果为:

www.cnblogs.com ? backurl = http % 3 A % 2 F % 2 Fwww.cnblogs.com % 3 Fa % 3 D1

场景二是关于查询字符串, 也要关于查询参数的名和值都举行编码.

把毛病纪录到服务器

假如把前后端的毛病信息集合举行汇总纪录, 能极大的轻易对数据库毛病日记的剖析.要把JavaScrpt毛病纪录到服务器须要借助image控件举行, 由于一切浏览器都支撑image对象, 而且能够防止跨域限定.

起首新建一个服务端页面用于处置惩罚毛病数据.这个页面从查询字符串中猎取毛病数据, 然后将数据写入到毛病日记中, 比方该页面为a.ashx.

然后在挪用页面中, 建立image对象, 并且为其src属性赋值, 如许就能够将毛病信息发送到服务端页面了.

function logError(msg) {
    var img = new Image();
    img.src = 'a.ashx?msg=' + encodeURIComponent(msg);
}
    原文作者:JS菌
    原文地址: https://segmentfault.com/a/1190000004447631
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞