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 相关文章推荐
Javascript attachEvent传递参数的办法
Dec 14 Javascript
js动画(animate)简单引擎代码示例
Dec 04 Javascript
JavaScript SetInterval与setTimeout使用方法详解
Nov 15 Javascript
网页下载文件期间如何防止用户对网页进行其他操作
Jun 27 Javascript
jQuery使用load()方法载入另外一个网页文件内的指定标签内容到div标签的方法
Mar 25 Javascript
分享十五款 jQuery 社交网络分享插件
May 16 Javascript
浅谈jquery之on()绑定事件和off()解除绑定事件
Oct 26 Javascript
JavaScript中transform实现数字翻页效果
Mar 08 Javascript
对于Javascript 执行上下文的全面了解
Sep 05 Javascript
angular2中Http请求原理与用法详解
Jan 11 Javascript
使用axios请求时,发送formData请求的示例
Oct 29 Javascript
element el-table表格的二次封装实现(附表格高度自适应)
Jan 19 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
BBS(php &amp; mysql)完整版(六)
2006/10/09 PHP
在Ubuntu 14.04上部署 PHP 环境及 WordPress
2014/09/02 PHP
实例讲解YII2中多表关联的使用方法
2017/07/21 PHP
PHP基于ip2long实现IP转换整形
2020/12/11 PHP
javascript JSON操作入门实例
2010/04/16 Javascript
Javascript匿名函数的一种应用 代码封装
2010/06/27 Javascript
jquery索引在使用中的一些困惑
2013/10/24 Javascript
js和jquery设置disabled属性为true使按钮失效
2014/08/07 Javascript
下拉框select的绑定示例
2014/09/04 Javascript
JQuery显示、隐藏div的几种方法简明总结
2015/04/16 Javascript
javascript学习总结之js使用技巧
2015/09/02 Javascript
JS日期加减,日期运算代码
2015/11/05 Javascript
Windows下使用Nodejs运行js的方法
2017/09/02 NodeJs
vue axios 二次封装的示例代码
2017/12/08 Javascript
微信小程序sessionid不一致问题解决
2019/08/30 Javascript
浅析Vue 防抖与节流的使用
2019/11/14 Javascript
vue 使用v-for进行循环的实例代码详解
2020/02/19 Javascript
解决VueCil代理本地proxytable无效报错404的问题
2020/11/07 Javascript
[03:49]DOTA2英雄基础教程 光之守卫
2014/01/14 DOTA
python服务器端收发请求的实现代码
2014/09/29 Python
在Python的Django框架下使用django-tagging的教程
2015/05/30 Python
python 请求服务器的实现代码(http请求和https请求)
2018/05/25 Python
解决python报错MemoryError的问题
2018/06/26 Python
python3+pyqt5+itchat微信定时发送消息的方法
2019/02/20 Python
解决Python3.8用pip安装turtle-0.0.2出现错误问题
2020/02/11 Python
python matplotlib 绘图 和 dpi对应关系详解
2020/03/14 Python
keras得到每层的系数方式
2020/06/15 Python
html5 web本地存储将取代我们的cookie
2012/12/26 HTML / CSS
阿姆斯特丹城市卡:Amsterdam Pass
2019/12/01 全球购物
你常见到的runtime exception
2016/09/05 面试题
教学器材管理制度
2014/01/26 职场文书
祖国在我心中的演讲稿
2014/05/04 职场文书
股东授权委托书范本
2014/09/13 职场文书
党的群众路线教育实践活动领导班子整改措施
2014/10/28 职场文书
Java SSH 秘钥连接mysql数据库的方法
2021/06/28 Java/Android
python中Pyqt5使用Qlabel标签播放视频
2022/04/22 Python