ECMA规定了常见的7种错误类型:
在跨浏览器编程时,预先检查错误类型是确定处理方式的途径之一,也就是先用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");//trueconsole.log(1==true);//true
改进:推荐使用全等(===)和非全等(!==)操作符,来避免发生因为使用相等和不等操作符时引发的类型转换错误;
console.log(1==="1");//falseconsole.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);}
新闻热点
疑难解答