一个程序通常有 3 种类型的异常,分别为 " 语法异常 " 、 " 运行时的异常 " 和 " 逻辑异常 " 。其中, " 语法异常 " 通常是在程序员输入一些编译器无法识别的代码后发生的; " 运行时的异常 " 通常是在运行时碰到一个错误时发生的,它与 " 语法异常 " 的区别在于,它不一定是 JavaScript 语言的错误引发的异常; " 逻辑异常 " 往往发生在程序设计时,程序没有按照预先设计的方式运行。
ECMA-262 第 3 版引入了 try-catch 语句,作为 JavaScript 处理异常的一种标准方式。
try {
// /_ 可能会导致的错误的代码_/
} catch (error) {
// /_ 在错误发生时怎么处理_/;
}
应把所有可能会抛出错误的代码都放 try 语句块中,而把那些用于错误处理的代码放 catch 中。
try {
a + b;
} catch (error) {
location.hash += ' 非法的变量 ';
}
如果 try 块中的任何代码出现了错误,就会立即退出代码执行过程,然后接着执行 catch 块。此时, catch 块会收到一个包含错误信息的对象。与其它语言不同的是,即使不使用这个错误对象,也要给它起个名。
错误对象中包含的实际信息因浏览器而异,但都有一个包含错误消息的 message 属性。
message 属性是唯一一个能够保证所有浏览器都支持的属性。除此之外, IE 添加了与 message 属性完全一样的 description 属性,还添加了保存着内部数据错误数量的 number 属性; Firefox 添加了 fileName 、 lineNumber 和 stack (包含栈跟踪技术)属性; Safari 添加了 line (表示行号)、 sourceId (表示内部错误代码)和 sourceURL 属性。当然,在跨浏览器编程时,仅建议使用 message 属性。
try {
a + b;
} catch (error) {
alert(error.message + ' 非法的变量 ');
}
当使用 try-catch 语句时候,浏览器默认自己把错误处理的无痕迹,因而不会报错。对于那些不要求用户懂技术,也不需要用户理解错误的 Web 应用程序,这应该说不是个理想的结果。不过 try-catch 能够让我们实现自己的错误处理机制。
使用 try-catch 最适合处理那些无法控制的错误。假设在使用一个大型 JavaScript 库中的函数,该函数可能会有意无意地抛出一些错误,由于我们不能随便修改这个库的源代码,所以大可以将对该函数的调用放在 try-catch 中,万一有什么错误的,也好恰当的处理。
在明明白白知道自己的代码会发生什么错误时,再使用 try-catch 就有点不合适了。
使用 finally , finally 是可选的。但,使用就会都执行。无论 try 或 catch 中包含什么代码 --- 甚至 return 语句,都不会阻止 finally 的执行。 如果有 finally 语句, catch 子句就变成可选的。
try {
// someStatements;
} catch (exception) {
// ## someStatements;
} finally {
// someStatements;
}
JavaScript 语言与 Java 语言不同, try...catch...finally 语句只能有一个 catch 语句。这是由于在 JavaScript 语言中无法指定出现异常的类型。
如果提供 finally 语句,则 catch 变成了可选的, IE7 及以前的版本中有一个 bug :除非有 catch 子句,否则 finally 中代码永不执行。如果考虑兼容之前的 IE 更早的版本,应提供一个 catch 子句,哪怕什么也不写,在 IE8 修复了该 bug 。
如果在 catch 区域中也发生了异常,可以在 catch 区域中再使用一组 try...catch 语句,即嵌套使用 try...catch 语句。
与 try-catch 搭配的操作符,用于随时抛出自定义错误。抛出错误时,必须给 throw 操作符指定一个值,这个值是什么类型却没有要求。
throw 1;
throw 'hi';
throw true;
throw { name: 'js' };
在使用 throw 操作符时,代码会立即停止执行,仅当有 try-catch 语句捕获到抛出的值后,代码才继续执行。
throw new Error('someStatements');
通过使用某种内置的错误类型,可以更真实的模拟浏览器的错误。每种错误类型的构造函数接受一个参数,即实际的错误消息。
throw new SyntaxError('SyntaxError');
throw new TypeError('TypeError');
throw new RangeError('RangeError');
throw new EvalError('EvalError');
throw new URLError('URLError');
throw new ReferenceError('ReferenceError');
在自定义错误类型时,最常使用的错误类型就是 Error 、 RangeError 、 ReferenceError 和 TypeError 。
还可以利用原型链通过继承 Error 来创建自定义的错误类型。此时,需要为新创建的错误类型来指定 name 和 message 属性。
function CustomError(message) {
this.name = 'CustomError';
this.message = message;
}
CustomError.prototype = new Error();
throw new CustomError('my message');
浏览器对待继承自 Error 的自定义错误类型,就像对待其它错误类型一样。如果要捕捉自己抛出的错误并把它与浏览器错误区别对待的话,创建自定义错误也是很有用的。
try {
var num = 1 / 0;
if (num == 'Infinity') {
throw new Error(' 被除数不可以为 0');
}
} catch (exception) {
alert(exception.message);
}
针对函数执行失败给出更多的信息,抛出自定义错误是一种很方便的方式。应该出现某种特定的已知错误条件,导致函数无法正常执行抛出异常。
在开发 JavaScript 中,重点关注函数和可能导致函数执行错误失败的因素。良好的错误机制应该可以确保代码中只发生自己抛出的错误。
一般来说,应用程序的较低层次中经常会抛出问题,但这个层次并不会影响当前代码的执行,因而错误得不到真正的处理。如果打算编写一个在很多程序中使用的 JavaScript 库,甚至只编写一个会在应用程序多个地方使用的辅助函数,建议使用时抛出错误提供更详细的信息。然后,就可以在应用程序中捕获并适当的处理这些错误。
在程序中,应该捕获那些确切地知道如何处理的错误。捕获错误的目的在于避免浏览器以默认方式处理,而抛出错误的目的是在于提供错误发生具体的原因的消息。
任何没有通过 try-catch 捕捉到的错误都会触发 window 对象的 error 事件。触发 onerror 事件是最早用于处理 JavaScript 异常的机制。页面出现异常时,将触发 onerror 事件,该事件在 Window 对象上触发。
在任何 Web 浏览器中, onerror 事件处理程序都不会创建 event 对象,但它可以接受 3 个 参数:错误消息、错误所在的 URL 和行号。多数情况下,只有错误消息有用。多数情况下,只有错误信息有用,因为 URL 只是能给文档的位置,而行号所指的就是即能够出自嵌入的 JavaScript 代码,也能够出自外部文件。
要指定 onerror 事件处理程序,必须使用如下的 DOM 0 级技术,它没有遵循 DOM 2 级事件的标准格式。
window.onerror = function (message, url, line) {
alert(message);
};
只要发生错误,不管是不是浏览器生成的,都会触发 error 事件,并执行这个事件处理程序。然后,浏览器默认的机制发挥作用,像往常一样显示出错误信息。
通过返回 false ,这个函数实际上就充当了整个文档中的 try-catch 语句,可以捕获所有的无代码处理的运行时错误。这个事件处理程序是避免浏览器报告错误的最后一道防线,理想情况下,只要可能就不应该使用它。只要能够适当的使用 try-catch 语句,就不会有错误误交给浏览器,也就不会触发 error 事件。
window.onerror = function (message, url, line) {
alert(message);
return false;
};
window.onerror = function () {
alert(' 您调用的函数不存在 ');
return true;
};
如果在 onerror 事件处理函数中没有使用 return true 语句,在弹出错误提示对话框后,浏览器的错误报告也会显示出来。为了隐藏此错误报告,函数需要返回 true 。
除了 Window 对象可以触发 onerror 事件之外,图像对象也可以触发 onerror 事件。
document.images[0].onerror = function () {
// somestatements;
return true;
};
参数 document.images[0] 用来表示页面中的第一个图像。
使用 onerror 事件处理异常除了可以捕捉异常之外,还可以提供如下 3 种信息来确定发生异常的详细信息。