错误处理与调试
(一)浏览器报告的错误
1.IE
2.Firefox
3.Safari
4.Opera
5.Chrome
(二)错误处理
1.try-catch语句
try{ //可能会导致错误的代码 }catch(error){ //发生错误时怎么处理 }
发生错误后catch接收一个包含错误信息的对象,它保存着错误消息的message属性。
①finally子句
finally子句一经使用,其代码无论如何都会执行。IE7及更早版本的BUG:除非有catch子句,否则finally的代码永远不会执行。只要代码包含finally子句,无论try还是catch语句块中的return语句都会被忽略。
②错误类型
Error:基类型。
EvalError:eval函数异常时。
RangeError:数值超出范围时。
ReferenceError:找不到对象。
TypeError:变量保存着意外的类型,或者在访问不存在的方法。
URIError:使用encodeURI或decodeURI而URI格式不正确。
②合理使用try-catch
最适合处理那些我们无法控制的错误。
2.抛出错误
throw操作符,用于随时抛出自定义错误,要给它指定一个值。
遇到throw操作符时,代码会立即停止执行,仅当有try-catch语句捕获到被抛出的值时,代码才会执行。
创建自定义错误消息时最常用的错误类型是Error、RangeError、ReferenceError和TypeError。
①抛出错误的时机
在某种特定的已知错误条件,导致函数无法正常执行时抛出错误。
②抛出错误与使用try-type
捕获错误的目的在于避免浏览器以默认方式处理它们,抛出错误的目的在于提供错误发生具体原因的消息。
3.错误事件
error事件处理程序捕获创建event对象,但可以接受三个参数:错误消息、错误所在的URL和行号。
window.onerror = function(message, url, line){ alert(message); return false; //阻止浏览器报告错误的默认行为 }; throw new Error("Something bad happened.");
4.处理错误的策略
5.常见的错误类型
①类型转换错误
发生在使用某个操作符,或者使用其他可能会自动转换值的数据类型的语言结构时。
使用==和!=操作符,或在if、for和while等流控制语句中使用非布尔值时。
②数据转换错误
与null进行比较只能确保相应的值不少null或undefined。
基本类型的值应该用typeof检测,而对象的值应该用instanceof来检测。
③通信错误
格式不正确的URL或发生的数据,最常见的是将数据发送给服务器之前没有用encodeURIComponent()对数据进行编码。
对于查询字符串,必须使用encodeURIComponent()方法。
6.区分致命错误和非致命错误
非致命错误:不影响用户的主要任务、只影响页面的一部分、可以修复、重复相同操作可以消除错误。
致命错误:应用程序根本无法继续运行、错误明显影响了用户的主要操作、会导致其他连带错误。
发生致命错误时应该给用户发送消息告诉他们无法继续手头的事情。
7.把错误记录到服务器
将错误写入保存服务器端错误的地方。
//从查询字符串中取得数据,然后将数据写入错误日志//参数:严重程度的数值或字符串及错误消息,使用Image对象来发送请求 function logError(sev, msg){ var img = new Image(); img.src = "log.php?sev=" + encodeURIComponent(sev) + "&msg=" + encodeURIComponent (msg); }
只要是使用try-catch语句,就应该吧相应错误记录到日志中。
(三)调试技术
1.将消息记录到控制台
在浏览器可以通过代码向控制台输出消息.IE8、Firefox、Chrome和Safari来说可以通过console对象向javascript控制台写入消息。
方法:error() info() log() warn()
使用LiveConnect
2.将消息记录到当前页面
在页面开辟一小块区域显示消息。
3.抛出错误
自定义错误通常使用asert抛出,可以接受两个参数:求值结果应该为true的条件和条件为false时要抛出的错误。
替换某些函数的if语句。
function divide(num1, num2){ assert(typeof num1 == "number" && typeof num2 == "number", "divide(): Both arguments must be numbers."); return num1 / num2; }
(四)常见的IE错误
1.操作终止
IE8之前,当<script>节点被包含在某个元素,而且javascript代码又要使用appendChild()、innerHTML或其他DOM方法修改该元素的父元素或祖先元素时,将会发生操作终止错误。
可以等到目标元素加载完毕后再对它进行操作,或者为document.body添加一个绝对定位在页面上的覆盖层。
//新的<div>元素被添加到document.body的开头而不是末尾,完成这部分的信息在脚本运行时是已知的 <div> <script type="text/javascript"> document.body.insertBefore(document.createElement("div"), document.body.firstChild); </script> </div>
也可以直接把<script>元素作为<body>的子元素。
2.无效字符
例如一个很像减号缺是有Unicode值8211表示的字符(\u2013),不能作为常规的减号。这个字符通常是在word文档自动插入的。
3.未找到成员
由于垃圾收集例程配合错误所直接导致。如果再兑现被销毁后又给该对象赋值,就会发生。最常见是使用event对象,IE的event对象有window属性,该对象在事件发生时创建,在最后一个事件处理程序执行完毕后销毁。如果再一个闭包使用了event对象,而该闭包不会立即执行,那么将来调用它并给event的属性赋值时,会导致未找到成员错误。
document.onclick = function () { var event = window.event; setTimeout(function(){ event.returnValue = false; //未找到成员错误 },1000); }
4.未知运行时错误
使用innerHTML或outerHTML以以下方式指定HTML时:把块元素插入行内元素 访问表格任意部分的任意属性
5.语法错误
6.系统无法找到指定资源
使用javascript请求某个资源URL,而该URL长度超过2083个字符时发生。