JavaScript 错误处理机制详解:onerror 与 try...catch 实战

作者:微光时间:2026-10-27 06:03:42浏览:291

本文深入解析 JavaScript 中的错误处理机制,涵盖语法错误与运行时异常的区别。详细对比了 BOM 的 onerror 事件与 ECMAScript 的 try...catch 语句,讲解如何捕获错误信息、处理图像加载失败及语法错误。同时介绍 Error 对象的属性、异常类型判断、手动抛出异常以及常用调试工具的使用。

一、错误分类

JavaScript 错误分类

1、语法错误:亦称解析错误,出现于传统语言的编译阶段或JavaScript的解释阶段。此类错误由代码中的意外字符直接导致,致使代码无法被编译或解释。一旦语法错误发生,代码执行将立即终止。在JavaScript中,仅同一线程内的代码受语法错误影响;其他线程或外部引用文件中的代码,若不与含错代码依赖,则可继续执行。


2、运行时错误:即异常(exception),发生于编译期或解释器之后。此时问题不在于代码语法,而在于尝试执行的操作在特定情境下非法。异常仅影响发生异常的线程,其他JavaScript线程可继续正常执行。



二、错误处理


错误处理机制:onerror 与 try...catch

JavaScript提供两种错误处理机制:BOM中的onerror事件处理函数方式,以及ECMAScript中的try...catch方式。


onerror 事件处理函数详解

1、onerror事件处理函数


这是首个用于协助JavaScript处理错误的机制。当页面出现异常时,error事件会在window对象上触发。例如:



代码如下:

 
<html>
<head>
<title>onerror Example</title>
<script type="text/javascript">
window.onerror = function() {
alert("发生错误!");
} 
</script>
</head>
<body onload="nonExistentFunction()">
</body>
</html>


上述代码在页面载入时尝试调用不存在的函数,从而引发异常并弹出“发生错误”信息。若需隐藏浏览器默认的错误提示,只需让onerror方法返回true。



代码如下:

 
<script type="text/javascript">
window.onerror = function() {
alert(“发生错误!”);
return true;
} 
</script>


1.1 取出错误信息



onerror处理函数提供三种信息以明确错误性质:


i) 错误信息——浏览器对给定错误显示的信息


ii) URL——发生错误的文件地址


iii) 行号——指定URL中错误发生的行号。


代码如下:

 
window.onerror = function(sMessage, sUrl, iLine) {
alert("发生错误!\n" + sMessage + "\nURL:" + sUrl + "\nLine Number:" + iLine);
return true;
} 


1.2 图像载入错误



window对象并非唯一支持onerror事件处理函数的对象,图像对象同样支持。当图像因文件不存在等原因加载失败时,error事件将在该图像上触发。例如:


代码如下:

 
<img src="noexist.gif" onerror="alert('载入图片时发生错误')"/>

上例直接在HTML中分配onerror事件处理函数。因noexist.gif不存在,故弹出警告框。也可通过脚本分配事件处理函数,但需在设置图像src属性前等待页面完全加载,例如:


代码如下:

 
<html>
<head>
<title>Image错误测试</title>
<script type="text/javascript">
function handleLoad() {
document.images[0].onerror = function() {
alert("载入图片时发生错误!");
}; 
document.images[0].src = "amigo.jpg";
} 
</script>
</head>
<body onload="handleLoad()">
<img/>
<body>
</html>

注意:与window对象的onerror事件处理函数不同,image的onerror事件不提供额外信息参数。



1.3处理语法错误



onerror事件处理函数不仅能处理异常,还能处理语法错误,且仅有它能处理语法错误。


首先,事件处理函数必须是页面中最早出现的代码。若语法错误出现在设置事件处理函数之前,该函数将失效,因为语法错误会完全停止代码执行。例如:


代码如下:

 
<html>
<head>
<title>onError Example</title>
<script type="text/javascript">
alert("Syntax error.";
window.onerror = function (sMessage, sUrl, iLine){
alert("An error occurrred:\n" + sMessage + "\nURL:" + sUrl + "\nLine Number:" + iLine );
return true;
} 
</script>
</head>
<body onload="nonExistentFunction()">
</body>
</html>

因突出显示的行(含语法错误)在分配onerror事件处理函数之前出现,浏览器直接报告该错误。错误后的代码不再被解释(线程已退出),故load事件触发调用nonExistentFunction()时,浏览器也会报错。书中称若将onerror分配置于语法错误之前,将显示两个警告框:一个显示语法错误,另一个显示异常。但实测结果仍报两个错误,未显示onerror事件中的信息。



使用onerror事件处理函数的主要问题在于其属于BOM部分,无标准控制其行为。因此,不同浏览器处理此事件的方式差异显著。例如,IE中发生error事件时,正常代码继续执行,变量和数据保留,可通过onerror事件处理函数访问。而在Mozilla中,正常代码执行终止,错误发生前的变量和数据均被销毁。



try...catch 语句与 Error 对象

2、try...catch方式



ECMPScript第三版引入了try…catch语句。基本语法如下:


代码如下:

 
try{
//code
[break;]
} catch ([exception]) {
//code
[break;]
} [finally{
//code
}] 

例如:


代码如下:

 
try {
window.openFile1();
alert("成功调用openFile1方法");
} catch (exception) {
alert("发生异常!");
} finally {
alert("try..catch测试结束!");
} 

与Java不同,ECMAScript标准在try…catch语句中仅允许一个catch语句,因为JavaScript是弱类型语言,无法指明catch子句中异常的具体类型。无论错误类型如何,均由同一个catch语句处理。Mozilla对此进行了扩展,支持多个catch语句,但因仅Mozilla可用,故不推荐。



finally用于包含无论是否有异常发生都要执行的代码,这对关闭打开的链接和释放资源非常有用。



2.1 嵌套 try...catch 语句



在 try...catch 语句的 catch 子句中也可能发生错误。此时,可使用嵌套的 try...catch 语句。示例:


代码如下:

 
try {
eval("a ++ b");
} catch(oException) {
alert("发生错误!");
try {
var aError = new Array(1000000000000000000000000000000000000000);
} catch(exception) {
alert("在catch子句中发生错误!");
} 
} finally{
alert("已完成")
} 


2.2 Error对象



发生错误时,JavaScript使用Error基类进行抛出。它包含两个特性:


i)name——表示错误类型的字符串


ii)message——实际的错误信息


Error对象的name对应于其类,可以是以下值之一:


EvalError:错误发生在eval()函数中;


RangeError:数字值超出JavaScript可表示的范围;


ReferenceError:使用了非法的引用;


SyntaxError:在eval()函数调用中发生了语法错误,其他语法错误由浏览器报告,无法通过try…catch处理;


TypeError:变量的类型不是预期所需的;


URIError:在encodeURI或decodeURI函数发生了错误。



2.3 判断错误类型



尽管每个 try...catch 语句中仅有一个catch子句,但判断抛出错误类型的方法主要有两种。第一种使用 Error 对象的 name 特性:


代码如下:

 
try {
eval("a ++ b");
} catch(oException) {
if (oException.name = "SyntaxError") {
alert("发生SyntaxError!");
} else {
alert("发生其他错误!");
} 
} 

第二种使用 instanceof 操作符,并使用不同错误的类名:


代码如下:

 
try {
eval("a ++ b");
} catch(oException) {
if (oException instanceof SyntaxError) {
alert("发生SyntaxError!");
} else {
alert("发生其他错误!");
} 
} 


2.4 抛出异常



在ECMAScript第三版中引入,用于有目的地抛出异常。抛出的错误对象可为字符串、数字、布尔值或实际对象,也可抛出Error对象(其构造函数仅接受一个参数,即错误信息)。如:


代码如下:

 
throw new Error("错误产生!");

开发人员抛出的错误和由浏览器自身抛出的错误均可在 try...catch 中捕获。例如:


代码如下:

 
function addTwoNumber(a, b) {
if (arguments.length < 2) {
throw new Error("需要传入两个数字!");
} 
} 
try {
result = addTwoNumber(90);
} catch(oException) {
if (oException instanceof SyntaxError) {
alert("SyntaxError:" + oException.message);
} else if (oException instanceof Error){
alert(oException.message);
} 
} 


三、调试技巧

调试技巧

如今的浏览器大多自带调试工具,大多数情况下已足够使用。此外,IE下可使用IETest,FireFox下可使用FireBug。



作者:Artwl


出处:http://artwl.cnblogs.com

作者最新文章