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

一、错误分类

  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

(0)

相关推荐

  • Javascript 错误处理的几种方法

    1.使用window.onerror指定错误处理函数. 当有错误的时候,onerror会被callback. 当某个JavaScript block中有多个script错误时,第一个错误触发后(回调callback),当前Javascript block后面的script会被自动Drop忽略掉,不被执行. 如:  复制代码 代码如下: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>

  • JavaScript高级程序设计 错误处理与调试学习笔记

    第十四章 错误处理与调试 1.开启浏览器错误报告 1.1 Internet Explorer □Toos → Internet Option → Anvanced → Display a notification about every script error 1.2 Firefox □Tools → Error Console (Firebug) 1.3 Safari □Edit → Preferences → Advanced → Show develop menu in menubar/

  • java自带的工具Jstack截取进程中的堆栈信息

    在Java软件的使用过程中,有时会莫名的出现奇怪的问题.而这些问题常常无法使用日志信息定位,这时我们就需要通过查看进程内部线程的堆栈调用关系来分析问题出在哪里. 举个例子,当我们在做某个操作时,莫名的会弹出多个警告框,其中有些信息是正常的,有些则不是.对于这些错误的警告信息,我们该如何定位是哪个位置的代码出现了错误弹出的框呢? 我们就需要在弹框以后,去查看软件的各个线程,去查找究竟是哪个线程导致了该问题.可是有时因为环境.时间等问题,我们根本不能拿着IDE去调试, 只能通过工具软件拍下内存快照,

  • JavaScript调用堆栈及setTimeout使用方法深入剖析

    Javascript中会经常用到setTimeout来推迟一个函数的执行,如: 复制代码 代码如下: setTimeout(function(){alert("Hello World");},1000); 会在执行到这句话后延迟1秒钟来弹出alert窗口.那么再看这一段: 复制代码 代码如下: function a(){ setTimeout(function() {alert(1)}, 0); alert(2); } a(); 注意这段代码中的setTimeout延迟设为了0,就是延

  • JavaScript错误处理和堆栈追踪详解

    有时我们会忽略错误处理和堆栈追踪的一些细节, 但是这些细节对于写与测试或错误处理相关的库来说是非常有用的. 例如这周, 对于 Chai 就有一个非常棒的PR, 该PR极大地改善了我们处理堆栈的方式, 当用户的断言失败的时候, 我们会给予更多的提示信息(帮助用户进行定位). 合理地处理堆栈信息能使你清除无用的数据, 而只专注于有用的数据. 同时, 当更好地理解 Errors 对象及其相关属性之后, 能有助于你更充分地利用 Errors. (函数的)调用栈是怎么工作的 在谈论错误之前, 先要了解下(

  • javascript Error 对象 错误处理

    Error对象 Property:   name: 错误名   number: 错误号   description: 描述   message: 错误信息,多同description  FF Only 属性   fileName: 错误发生的文件   stack: 错误发生时的调用堆栈 Constructor:   Error(){     this(0,"")} Error(description){     this(0,description)} Error(number,des

  • JavaScript 错误处理与调试经验总结

    下面总结一下JS错误处理与调试的方法 方法1:用alert() 和document.write()方法监视变量值. alert()在弹出对话框显示变量值的同时,会停止代码的继续运行,直到用户单击"确定"按钮,而document.write()则在输出值后继续运行代码.调试JS时可以根据具体情况来选择这种方法. 例如下面代码:将数组a中以1开头的数据添加到数组b中 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.

  • 输出java进程的jstack信息示例分享 通过线程堆栈信息分析java线程

    复制代码 代码如下: #!/bin/shpro_name=java #process namekeys=`ps -ef |grep "$pro_name" |grep -v "grep" | awk '{print $2}'`nowdate=`date +%Y%m%d%H%M%S` jstackpath="/usr/java/jdk1.6.0_07/bin/jstack"cpulogpath="/home/" for key

  • JS实现队列与堆栈的方法

    本文实例讲述了JS实现队列与堆栈的方法.分享给大家供大家参考,具体如下: 在面向对象的程序设计里,一般都提供了实现队列(queue)和堆栈(stack)的方法,而对于JS来说,我们可以实现数组的相关操作,来实现队列和堆栈的功能,看下面的相关介绍. 一.看一下它们的性质,这种性质决定了它们的使用场合 队列:是一种支持先进先出(FIFO)的集合,即先被插入的数据,先被取出! 堆栈:是一种支持后进先出(LIFO)的集合,即后被插入的数据,先被取出! 二.看一下实现的代码(JS代码) var a=new

  • JavaScript错误处理

    一.错误分类 1. 语法错误 也称为解析错误,发生在传统编程语言的编译时,在JavaScript中发生在解释时,这些错误是由代码中的意外字符直接引起的,然后就不能直接编译/解释,eg,在一行代码因缺少右括号,产生了语法错误.发生语法错误时,就不能继续执行代码.在JavaScript中,只有在同一个线程中的代码会受语法错误的影响.在其他线程中的代码和其他外部引用的文件中的代码,如果不依赖于包含错误的代码,则可以继续执行. 2. 运行时错误 也称为异常(exception,在编译期/解释器后).此时

随机推荐