JavaScript高级程序设计 阅读笔记(二十) js错误处理


Posted in Javascript onAugust 14, 2012

一、错误分类

1、语法错误:也称解析错误,发生在传统语言的编译时,在JavaScript中发生在解释时。这些错误是由代码中的意外字符直接引起的,然后就不能直接编译/解释。发生语法错误时,就不能继续执行代码。在JavaScript中,只有在同一个线程中的代码会受语法错误的影响。在其他线程中的代码和其他外部引用的文件中的代码,如果不依赖于包含错误的代码,则可以继续执行。

2、运行时错误:也称为异常(exception,在编译期/解释器后)。此时,问题并不出在代码的语法上,而是,尝试完成的一个操作,在某些情况下是非法的。异常只影响发生的线程,其他JavaScript线程即可继续正常的执行。

二、错误处理

JavaScript提供了两种处理错误的方式:BOM中的onerror事件处理函数方式和ECMAScript中的try...catch方式。

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的一部分,所以,没有任何标准能控制它的行为。因此,不同的浏览器使用这个事件处理错误的方式有明显的不同,eg,在IE中发生error事件时,正常的代码会继续执行,所有的变量和数据都保留下来,并可通过onerror事件处理函数访问。在Mozilla中,正常的代码执行都会结束,同时所有的错误发生之前的变量和数据都被销毁。

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

Javascript 相关文章推荐
js程序中美元符号$是什么
Jun 05 Javascript
js css后面所带参数含义介绍
Aug 18 Javascript
引入JS文件IE6报语法错误或缺少对象问题的解决方法
Jan 09 Javascript
JavaScript中数据结构与算法(二):队列
Jun 19 Javascript
BootStrap使用file-input插件上传图片的方法
Sep 05 Javascript
微信小程序实现点击按钮修改文字大小功能【附demo源码下载】
Dec 06 Javascript
Element-ui table中过滤条件变更表格内容的方法
Mar 02 Javascript
解决layer弹层遮罩挡住窗体的问题
Aug 17 Javascript
Vue路由模块化配置的完整步骤
Aug 14 Javascript
Node.js实现批量下载图片简单操作示例
Jan 18 Javascript
vue使用openlayers实现移动点动画
Sep 24 Javascript
JS addEventListener()和attachEvent()方法实现注册事件
Jan 11 Javascript
JavaScript高级程序设计 阅读笔记(十八) js跨平台的事件
Aug 14 #Javascript
JavaScript高级程序设计 阅读笔记(十七) js事件
Aug 14 #Javascript
JavaScript高级程序设计阅读笔记(十六) javascript检测浏览器和操作系统-detect.js
Aug 14 #Javascript
JavaScript高级程序设计 阅读笔记(十四) js继承机制的实现
Aug 14 #Javascript
JavaScript高级程序设计 阅读笔记(十三) js定义类或对象
Aug 14 #Javascript
JavaScript高级程序设计 阅读笔记(十二) js内置对象Math
Aug 14 #Javascript
jQuery 1.8 Release版本发布了
Aug 14 #Javascript
You might like
DC这些乐高系列动画电影你看过几部?
2020/04/09 欧美动漫
dedecms采集中可以过滤多行代码的正则表达式
2007/03/17 PHP
php实现将上传word文件转为html的方法
2015/06/03 PHP
php比较相似字符串的方法
2015/06/05 PHP
Centos7 Yum安装PHP7.2流程教程详解
2019/07/02 PHP
Javascript中的异步编程规范Promises/A详细介绍
2014/06/06 Javascript
更快的异步执行(setTimeout多浏览器)
2014/08/12 Javascript
form.submit()不能提交表单的错误原因及解决方法
2014/10/13 Javascript
jQuery中hide()方法用法实例
2014/12/24 Javascript
js随机生成26个大小写字母
2016/02/12 Javascript
教你用Cordova打包Vue项目的方法
2017/10/17 Javascript
JavaScript运行原理分析
2018/02/09 Javascript
Node.js 多线程完全指南总结
2019/03/27 Javascript
使用mixins实现elementUI表单全局验证的解决方法
2019/04/02 Javascript
vue中axios实现数据交互与跨域问题
2019/05/12 Javascript
ES6中字符串的使用方法扩展
2019/06/04 Javascript
VUE组件中的 Drawer 抽屉实现代码
2019/08/06 Javascript
layui异步加载table表中某一列数据的例子
2019/09/16 Javascript
vue 页面回退mounted函数不执行的解决方案
2020/07/26 Javascript
vue配置多代理服务接口地址操作
2020/09/08 Javascript
swiper自定义分页器的样式
2020/09/14 Javascript
原生js实现购物车功能
2020/09/23 Javascript
openlayers实现图标拖动获取坐标
2020/09/25 Javascript
[01:07:20]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第二场 2月2日
2021/03/11 DOTA
Python SQLite3数据库操作类分享
2014/06/10 Python
探寻python多线程ctrl+c退出问题解决方案
2014/10/23 Python
基于python纯函数实现井字棋游戏
2020/05/27 Python
毕业生求职找工作的自我评价范文
2013/11/27 职场文书
中专毕业生自我鉴定
2014/02/02 职场文书
电力培训心得体会
2014/09/02 职场文书
信用卡逾期证明示例
2014/09/13 职场文书
大学毕业晚会开场白
2015/05/29 职场文书
可可西里观后感
2015/06/08 职场文书
CSS中妙用 drop-shadow 实现线条光影效果
2021/11/11 HTML / CSS
Java 异步任务计算FutureTask
2022/04/28 Java/Android
详解CSS3浏览器兼容
2022/12/24 HTML / CSS