错误处理非常重要的部分是首先识别错误可能会在代码中的什么地方发生。因为JavaScript 是松散
类型的,不会验证函数参数,所以很多错误只有在代码真正运行起来时才会出现。通常,需要注意3 类
错误:
类型转换错误
数据类型错误
通信错误
上面这几种错误会在特定情况下,在没有对值进行充分检测时发生。
静态代码分析器
不得不说的是,通过在代码构建流程中添加静态代码分析或代码检查器(linter),可以预先发现非
常多的错误。这样的代码分析工具有很多,详见GitHub Gist 网站All Gists 页面。常用的静态分析工具是JSHint、JSLint、Google Closure 和TypeScript。
静态代码分析器要求使用类型、函数签名及其他指令来注解JavaScript,以此描述程序如何在基本
可执行代码之外运行。分析器会比较注解和JavaScript 代码的各个部分,对在实际运行时可能出现的潜
在不兼容问题给出提醒。
类型转换错误
类型转换错误的主要原因是使用了会自动改变某个值的数据类型的操作符或语言构造。使用等于
()或不等于(!=)操作符,以及在if、for 或while 等流控制语句中使用非布尔值,经常会导致
类型转换错误。
第3 章曾讨论过,相等和不相等操作符会自动把执行比较的两个不同类型的值转换为相同类型。在
非动态语言中,符号之间是直接比较的,因此很多开发者在JavaScript 中也会以相同方式来错误地比较
值。大多数情况下,最好使用严格相等(=)和严格不相等(!==)操作符来避免类型转换。来看下
面的例子:
console.log(5 == “5”); // true
console.log(5 === “5”); // false
console.log(1 == true); // true
console.log(1 === true); // false
这个例子分别使用了相等和严格相等操作符比较了数值5 和字符串"5"。相等操作符会把字符串"5"
转换为数值5,然后再进行比较,结果是true。严格相等操作符发现两个值的数据类型不同,因而直
接返回false。同样,对于1 和true 的比较也类似。相等操作符认为它们相等,但严格相等操作符认
为它们不相等。使用严格相等和严格不相等操作符可以避免比较过程的类型转换错误,强烈推荐用它们
代替相等和不相等操作符。
类型转换错误也会发生在流控制语句中。比如,if 语句会自动把条件表达式转换为布尔值,然后
再决定下一步的走向。在实践中,if 语句是问题比较多的。来看下面的例子:
function concat(str1, str2, str3) {
let result = str1 + str2;
if (str3) { // 不要!
result += str3;
}
return result;
}
这个函数的用意是把两个或三个字符串拼接起来并返回结果。第三个字符串是可选的,因此必须检
测它是否存在。如第3 章所说,命名变量如果没有被赋值就会自动被赋予undefined 值。而在默认转换中,undefined 会被转换为布尔值false。因此这个函数的用意是在提供了第三个参数的情况下,
才会在拼接时带上它。问题在于并非只有undefined 会转换为false,字符串也不是唯一可转换为true
的值。假如第三个参数是数值0,if 条件判断就会失败,而数值1 则会导致满足条件。
在流控制语句中使用非布尔值作为条件是很常见的错误来源。为避免这类错误,需要始终坚持使用
布尔值作为条件。这通常可以借助某种比较来实现。例如,可以把前面的函数改写为如下形式:
function concat(str1, str2, str3){
let result = str1 + str2;
if (typeof str3 === “string”) { // 恰当的比较
result += str3;
}
return result;
}
在这个重写的版本中,if 语句的条件会基于比较操作返回布尔值。这个函数相对更安全,受错误
值影响的可能性也更小。
10-11
6122
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)