错误处理(二):常见错误类型
错误处理的核心,是首先要知道代码里会发生什么错误。一般来说,需要关注三种错误类型:类型转换错误,数据类型错误,通信错误
类型转换错误
1、在使用相等(==)和不相等(!=)操作符,或者使用其他可能会自动转换值的数据类型的语言结构时
console.log( 5=='5' ) //true console.log( 5==='5' ) //false console.log( 1==true ) //true console.log( 1===true ) //false
这里使用了想等和全等操作符比较了数值5和字符串‘5’,相等操作符首先会将数值5转换称字符串‘5’,然后再将其与另一个字符串'5'进行比较,结果是true
对于1和true也是如此
2、流控制语句。像if之类的语句再确定下一步操作之前,会自动把任何值转换成布尔值。尤其是if语句,如果使用不当,最容易出错
function concat(str1,str2,str3){ var result = str1 + str2; if(str3){ //绝对不要这样!! result += str3; } return result }
未使用过的命名变量会自动被赋予undefned值。而undefined值可以被转换成布尔值。问题在于,并不是只有undefined才会被转换成false,也不是只有字符才可以转换成true.
假设第三个参数是0,那么if语句的测试就会失败。而对数值1对测试则会通过
function concat(str1,str2,str3){ var result = str1 + str2; if(typeof str3 == 'string'){ //恰当对比较 result += str3; } return result }
在重写后的函数中,if语句的条件会基于比较返回一个布尔值。这个函数相对可靠得多。
数据类型错误
1、在前面的例子,通过检测第三个参数可以确保它是一个字符串。但是并没有检测另外两个参数,如果该函数必须要返回一个字符串,那么只要传入两个数值,忽略第三个参数,就可以轻易导致它的执行结果错误。
2、
//不安全的函数,任何非字符串值都会导致错误 function getQueryString(url){ var pos = url.indexOf('?'); if(pos > -1){ return url.substring(pos + 1); } return ''; }
这个函数的用意是返回给定url中的查询字符串,首先使用indexOf()寻找字符串中问号,如果找到了,利用substring()方法返回问号后面的所有字符串
这个例子中的两个函数只能操作字符串,因此只要传入其他数据类型的值就会导致错误。而添加一条简单的类型检测语句,就可以确保函数不那么容易出错
function getQueryString(url){ if(typeof url == 'string'){ //通过检测类型确保安全 var pos = url.indexOf('?'); if(pos > -1){ return url.substring(pos + 1); } } return ''; }
重写后的这个函数首先检查了传入的是不是字符串。这样,确保了函数不会因为接收到非字符串值而导致错误。
3、流控制语句中使用非布尔值作为条件很容易导致类型转换错误
//不安全的函数,任何非数组值都会导致错误 function reverseSort(values){ if(values){ //绝对不要这样!! values.sort(); values.reverse(); } }
其中用到了sort()和reverse()方法。对于if语句到控制条件而言,任何会转换为true的非数组值都会导致错误。
另一个常见的错误就是将参数与null值进行比较
//不安全的函数,任何非数组值都会导致错误 function reverseSort(values){ if(values != null){ //绝对不要这样!! values.sort(); values.reverse(); } }
与null进行比较只能确保相应的值不是null和undefined,要确保传入的值有效,仅检测null值是不够的;因此,不应该使用这个技术。
在确切知道应该传入什么类型的情况下,最好是使用instanceof来检测数据类型
//安全,非数组值将被忽略 function reverseSort(values){ if(values instanceof Array){ //问题解决了 values.sort(); values.reverse(); } }
大体上来说,基本类型的值应该使用typeof来检测,而对象的值则应该使用instanceof来检测。
通信错误
随着ajax编程的兴起,web应用程序在其生命周期内动态加载信息或功能已经成为一件司空见惯的事。不过,js与服务器之间的任何一次通信,都有可能产生错误。
在将数据发送到服务器之前,没有使用encodeURIComponent()对数据进行编码
http://www.yourdomain.com/?redir=http://www.someotherdomain.com?a=b&c=d
上面的url的格式就是不正确的,针对‘redir=’后面的所有字符串调用encodeURIComponent()就可以解决这个问题,结果产生如下
http://www.yourdomain.com?redir%3Dhttp%3A%2F%2Fwww.someotherdomain.com%3Fa%3Db%26c%3Dd
对于查询字符串,应该记住必须要使用encodeURIComponent()方法。
在服务器响应不正确是,也会发生通信错误。在使用ajax通信的情况下,也可能发生通信错误。