读javascript高级程序设计14-错误处理与调试
一 错误类型
ECMA规定了常见的7种错误类型:
- Error: 基类型.其他常见的错误类型都继承自该类型,一般供开发人员抛出自定义错误.
- EvalError:该类型会在eval()函数使用异常时被抛出.例如:new eval();.实际上在某些版本浏览器下会抛出TypeError,而且本身eval()函数在实际开发中就要谨慎使用,所以抛出EvalError的几率是很小的.
- RangeError:在数值超出范围时触发.例如:new Array(-1)//RangeError: invalid array length.
- ReferrerError: 通常在访问不存在的变量时会触发该错误.例如:console.log(a);//ReferenceError: a is not defined
- SyntaxError:一般把语法错误的JavaScript字符串传给eval()函数时会触发该类型错误.eval("console.log(a)+")
- TypeError:当执行特定操作时,如果变量类型不符合就会发生类型错误.常见的几种情形是:访问不存在的方法,函数传入参数类型不符合等.
- URIError:在使用encodeURI()和decodeURI()方法,而URI的格式不正确时会发生该错误.
在跨浏览器编程时,预先检查错误类型是确定处理方式的途径之一,也就是先用try-catch语句捕捉到错误,然后在catch块中使用 instanceof操作符判断错误类型,最后根据不同的错误类型做出相应的处理.
try {
new 1;
}
catch (error) {
if (error instanceof EvalError) {
console.log('eval参数错误');
}
else if (error instanceof TypeError) {
console.log('类型错误');
} else {
console.log(error.message);
}
}
二 捕捉错误与抛出错误
1.try-catch语句捕捉错误
try-catch语句是常用的捕捉错误的方式。其中catch会接到一个包含错误信息的对象error,即使不使用该对象,也要给它取个名字,否则会发生语法错误。catch中对象error有个通用的属性message保存具体的错误信息。
try {
window.a();
} catch (error) {
alert(error.message);
}
finally子句:对于包含finally子句的情况,无论是执行try分支还是catch分支,最后肯定都会执行finally分支。即使中间有return语句也不能阻止finally子句的执行。
try {
console.log(1);
} catch (error) {
console.log(2);
} finally {
console.log(3);
}
try-catch适合处理那些我们无法控制的错误。
2.抛出错误
throw操作符用来抛出错误,当遇到该操作符时代码会立即停止执行,仅当try-catch语句捕捉到被抛出的值时,代码才会继续执行.通过使用某种内置的错误类型时,可以更真实的模拟浏览器错误.例如:
throw new Error("test throw error");
比较常用的错误类型是Error,RangeError,ReferenceError,TypeError.
利用原型链可以通过继承Error来创建自定义错误类型.例如:
function MyError(message) {
this.name = 'MyError';
this.message = message;
}
MyError.prototype = new Error();
throw new MyError('this is my test error;');
对于代码量大的程序,根据原生的报错信息往往很难直接定位错误.这时候带有适当信息的自定义错误就能够显神通了,显著提升了代码的可维护性.在开发过程中,尤其要关注的是函数以及容易导致函数执行失败的位置,比如对参数类型的检验等.例如:
function test(value) {
if (!(value instanceof Array)) {
throw new Error('test():参数不是数组');
}
return value.sort();
}
总之,抛出错误的目的是为了提供错误发生具体原因相关的详细信息;而捕捉错误的目的是避免浏览器以默认方式处理错误.
三 几种常见错误场景
JavaScript是松散类型的,而且在函数传参时不会检验参数类型,因此错误都是发生在代码运行期间的.常见的三种错误类型为:类型转换错误,数据类型错误和通信错误.
1.类型转换错误
类型转换错误常发生在使用某个操作符或者自动转换数据类型的场景.
第一种常见错误是使用相等和不等操作符
console.log(1=="1");//true
console.log(1==true);//true
改进:推荐使用全等(===)和非全等(!==)操作符,来避免发生因为使用相等和不等操作符时引发的类型转换错误;
console.log(1==="1");//false
console.log(1===true);//false
第二种常见错误是在流控制语句中使用非布尔值.
function concat(str1,str2){
if(str2){
return str1+str2;
}
else{
return str1;
}
}
concat('a',0);//a"
concat('a',1);//"a1"
该方法的目的是当第二个参数存在的时候返回两个字符串拼接结果;当第二个参数不存在的时候直接返回第一个参数.可是除了undefined会转换为布尔值false外,0也会转换为false,而1则转换为true.因此调用结果与本意不太一致.
改进:
function concat(str1,str2){
if(typeof str2=="string"){
return str1+str2;
}
else{
return str1;
}
}
concat('a',0);//a"
concat('a',1);//"a"
2.数据类型错误
在JavaScript中,使用变量和函数参数之前是不会自动进行类型检验的.因此需要开发人员自己编写数据类型检测的代码.例如:
function reverseSort(values) {
if (values) {//这里的判断不能保证是数组类型
values.sort();
values.reverse();
} console.log(values);
}
reverseSort("a");//TypeError
这里如果传入的参数不是数组类型,就会发生数据类型错误.一般来说,对于基本类型使用typeof进行类型检验,对于对象类型使用instanceof进行类型检验.
function reverseSort(values) {
if (values instanceof Array) {
values.sort();
values.reverse();
}
console.log(values);
}
reverseSort("a");//a"
reverseSort([6,2,3,8,1,5]);//[8, 6, 5, 3, 2, 1]
3.通信错误
场景一是在将数据发送给服务器之前,未使用encodeURIComponent()对数据进行编码.例如:
www.cnblogs.com?backurl=http
://www.cnblogs.com?a=1
解决方法是使用encodeURIComponent()对backurl后面的参数进行编码,结果为:
www.cnblogs.com?backurl= http%3A%2F%2Fwww.cnblogs.com%3Fa%3D1
场景二是对于查询字符串,也要对于查询参数的名和值都进行编码.
四 把错误记录到服务器
如果把前后端的错误信息集中进行汇总记录,能极大的方便对数据库错误日志的分析.要把JavaScrpt错误记录到服务器需要借助image控件进行,因为所有浏览器都支持image对象,而且可以避免跨域限制.
首先新建一个服务端页面用于处理错误数据.这个页面从查询字符串中获取错误数据,然后将数据写入到错误日志中,例如该页面为a.ashx.
然后在调用页面中,创建image对象,并且为其src属性赋值,这样就可以将错误信息发送到服务端页面了.
function logError(msg) {
var img = new Image();
img.src = 'a.ashx?msg=' + encodeURIComponent(msg);
}
读javascript高级程序设计14-错误处理与调试的更多相关文章
- 《JAVASCRIPT高级程序设计》错误处理与调试
一.错误处理 错误处理在程序设计中的重要性是毋庸置疑的,任何有影响力的web应用程序都需要一套完善的错误处理机制.良好的错误机制可以让用户得到提醒,知道发生了什么事. 1.try-catch语句 tr ...
- 读javascript高级程序设计00-目录
javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...
- 读javascript高级程序设计-目录
javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...
- 读javascript高级程序设计08-引用类型之Global、Math、String
一.Global 所有在全局作用域定义的属性和方法,都属于Global对象. 1.URI编码: encodeURI():主要用于对整个URI编码.它不会对本身属于URI的特殊字符进行编码. encod ...
- 读javascript高级程序设计02-变量作用域
一. 延长作用域链 有些语句可以在作用域前端临时增加一个变量对象,该变量对象在代码执行完成后会被移除. ①with语句延长作用域. function buildUrl(){ var qs=" ...
- 读javascript高级程序设计10-DOM
一.节点关系 元素的childNodes属性来表示其所有子节点,它是一个NodeList对象,会随着DOM结构的变化动态变化. hasChildNodes():是否有子节点. var headline ...
- 读javascript高级程序设计17-在线检测,cookie,子cookie
一.在线状态检测 开发离线应用时,往往在离线状态时把数据存在本地,而在联机状态时再把数据发送到服务器.html5提供了检测在线状态的方法:navigator.onLine和online/offline ...
- 读Javascript高级程序设计第三版第六章面向对象设计--创建对象
虽然Object构造函数或者对象字面量都可以用来创建单个对象,但是缺点非常明显:使用同一接口创建很多对象,会产生大量重复代码. 工厂模式 1 function CreatePerson(name,a ...
- 读javascript高级程序设计01-基本概念、数据类型、函数
一. javascript构成 1.javascript实现由三部分组成: ECMAScript:核心语言功能 DOM:文档对象模型,提供访问和操作网页内容的方法和接口 BOM:浏览器对象模型,提供与 ...
随机推荐
- for循环和迭代
迭代的一个时间复杂度最大就是n^2,而在for循环和迭代相结合的一个情况下则是一个排序组合,不再是一个简单n^2,而是阶乘n!.
- ASP.NET MVC controller 之间传JS值
在ASP.NET MVC中有东西叫TempData,它的类型是TempDataDictionary,它与ViewData以及ViewBag的不同之处在于 它的内部是使用session来保存信息的,可以 ...
- 前端里神奇的BFC 原理剖析
以前在做自适应两栏布局的时候别人口中听到bfc这个词,于是看了各种关于bfc的文章,发现梦想天空介绍的不错,今天就在他的基础上润色一下. 一.BFC是什么? 在解释 BFC 是什么之前,需要先介绍 B ...
- 网站中集成jquery.imgareaselect实现图片的本地预览和选择截取
imgAreaSelect 是由 Michal Wojciechowski开发的一款非常好用的jquery插件,实现了图片的截取功能.其文档和Demo也是很详尽的.大家可以到http://odynie ...
- 批处理命令——if
[1]if命令简介 if,大家肯定见多了,一个没有用过if的程序员不是一个好产品经理(呵呵~~). if,判断选择的作用,自从写了几年代码,我才真正弄明白了一件事,为什么当初上学时候考试总要做那么多的 ...
- MVC(二)
所谓EF延迟加载,就是使用Lamabda或Linq查询数据时,EF并不会将数据直接查询出来,而是在用到的这个查询结果的时候才会加载到内存中.延迟加载也可以理解成 按需加载,顾名思义,就是按照所需的数据 ...
- .naturalWidth 和naturalHeight属性,
在HTML 5中,新增加了两个用来判断图片的宽度和高度的属性,分别为 .naturalWidth 和naturalHeight属性,例子如下: var rw = myimage.naturalWidt ...
- CI框架区分前后台
基于官网 CodeIgniter-3.1.2版本修改 1.复制根目录下的 index.php 文件,重名为 admin.php .index.php用作前台入口:admin.php用作后台入口. 打 ...
- Oracle logmnr工具分析日志脚本
在oracle:对logmnr工具分析日志这个不陌生:对数据恢复应用场景经常用到:这里为了方便对归档日志进行分析: 当然网上有一个logmnr界面的工具:感觉很人性化:下载需要积分:为此写一个脚本. ...
- Linux常用命令(四)
1.xargs 作用是将参数列表转换成小块分段传递给其他命令,以避免参数列表过长的问题 语法格式: # xargs [-ni] 常用参数: 参数 参数说明 -n 分组输出,n个分为一组 -i 与大括号 ...