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 相关文章推荐
Node.js抓取中文网页乱码问题和解决方法
Feb 10 Javascript
Bootstrap每天必学之按钮
Nov 26 Javascript
关于JavaScript限制字数的输入框的那些事
Aug 14 Javascript
SpringMVC+bootstrap table实例详解
Jun 02 Javascript
jQueryeasyui 中如何使用datetimebox 取两个日期间相隔的天数
Jun 13 jQuery
详解Vue.js搭建路由报错 router.map is not a function
Jun 27 Javascript
Angularjs的启动过程分析
Jul 18 Javascript
Vue自定义指令使用方法详解
Aug 21 Javascript
Vue项目中添加锁屏功能实现思路
Jun 29 Javascript
jQuery设置下拉框显示与隐藏效果的方法分析
Sep 15 jQuery
javascript 易错知识点实例小结
Apr 25 Javascript
node中使用shell脚本的方法步骤
Mar 23 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
php+mysql 实现身份验证代码
2010/03/24 PHP
Yii框架在页面输出执行sql语句以方便调试的实现方法
2014/12/24 PHP
php自动载入类用法实例分析
2016/06/24 PHP
PHP表单验证内容是否为空的实现代码
2016/11/14 PHP
yii2 上传图片的示例代码
2018/11/02 PHP
Nigma vs AM BO3 第二场2.13
2021/03/10 DOTA
javascript 广告后加载,加载完页面再加载广告
2010/11/25 Javascript
js实现卡片式项目管理界面UI设计效果
2015/12/08 Javascript
Bootstrap实现带暂停功能的轮播组件(推荐)
2016/11/25 Javascript
Express URL跳转(重定向)的实现方法
2017/04/07 Javascript
vue实现验证码输入框组件
2017/12/14 Javascript
Vue中通过Vue.extend动态创建实例的方法
2019/08/13 Javascript
vue.js 输入框输入值自动过滤特殊字符替换中问标点操作
2020/08/31 Javascript
Vue ​v-model相关知识总结
2021/01/28 Vue.js
Python多线程编程简单介绍
2015/04/13 Python
在Python的Bottle框架中使用微信API的示例
2015/04/23 Python
python图像常规操作
2017/11/11 Python
python读取几个G的csv文件方法
2019/01/07 Python
详解python列表生成式和列表生成式器区别
2019/03/27 Python
python图形工具turtle绘制国际象棋棋盘
2019/05/23 Python
开启Django博客的RSS功能的实现方法
2020/02/17 Python
python-sys.stdout作为默认函数参数的实现
2020/02/21 Python
Pytorch 图像变换函数集合小结
2021/02/01 Python
浅谈利用缓存来优化HTML5 Canvas程序的性能
2015/05/12 HTML / CSS
Sahajan美国:阿育吠陀护肤品牌
2021/01/09 全球购物
康拓普公司Java笔面试
2016/09/23 面试题
Java多态性的定义以及类型
2014/09/16 面试题
请问如下代码执行后a和b的值分别是什么
2016/05/05 面试题
药品促销活动方案
2014/02/14 职场文书
打架检讨书2000字
2014/02/22 职场文书
小学课外活动总结
2014/07/09 职场文书
房产协议书范本
2014/10/18 职场文书
工作保证书怎么写
2015/02/28 职场文书
少年雷锋观后感
2015/06/10 职场文书
PHP对接阿里云虚拟号的实现(号码隐私保护)
2021/04/06 PHP
redis的list数据类型相关命令介绍及使用
2022/01/18 Redis