正文
try catch
在 JavaScript 中进行错误处理,最常见的方式就是使用try catch
语句。将容易出错的代码段放入try
块中,即可捕获错误,程序便至少不会因为一个错误而崩溃。
1. catch(error)
所有浏览器都支持error.message
属性,它包含了错误的基本必要信息。而且在error
对象中,基本也就该属性比较有用。所以,最好还是只用message
属性。
2. finally
如果你加入了finally
子句,那么它其中的代码无论如何都会执行,即使在try
或catch
中使用return
function f() {
try {
throw new Error('出错了')
return 0
} catch (e) {
console.log(e.message)
return 1
} finally {
return 2
}
}
console.log(f())
上面代码的执行结果为:出错了,2。
即使在try
中没有抛出异常,也会如此。
请慎重添加finally
3. 错误对象的类型
error
对象有许多类型,如
throw new TypeError('类型错误')
throw new ReferenceError('引用错误')
等。
如果想在catch
语句中判断错误的类型,可以使用instanceof
关键字判断,如
function f() {
try {
throw new TypeError('类型错误')
} catch (e) {
if (e instanceof TypeError) {
console.log('类型错误')
} else if (e instanceof ReferenceError) {
console.log('引用错误')
}
}
}
f()
上面的代码执行结果是:类型错误
顺便提一下,你可以自定义一个类型错误,如果感兴趣请百度。
4. 抛出错误的时机
良好的错误处理机制应确保代码中只发生你自己发出的错误
尽可能考虑代码的健壮性,在可能出错的代码段,进行捕获。
如果代码段是第三方库中的代码,无法修改的情况下,使用try catch
是一个很棒的方式。
如果是自己编写的代码,应保证程序不会被动地抛出错误,除非是你主动抛出,即所有可能抛出的错误都应是你考虑范围内并有一定措施来解决。这时候也应当适应try catch
5. 常见的产生错误原因
a. 类型转换错误
尤其会发生在if
语句。
function f(str1, str2, str3) {
let result = str1 + str2
if (str3) {
result += str3
}
return result
}
此函数的用意为拼接三个字符串,第三个字符串是可选的,所以要对第三个字符串进行检查。
如果没有传入第三个参数,则str3
为undefined
,转化成布尔值是false
。
但是,并不是undefined
才能转化为false
,也不是字符串才能转化为true
。如果传入的第三个参数是数值0
,则if
不通过;如果是数值1
,则可以通过。
所以尽量不要对流程控制语句中使用非布尔值
上述代码可以改为
function f(str1, str2, str3) {
let result = str1 + str2
if (typeof str3 === 'string') {
result += str3
}
return result
}
b. 数据类型错误
- 我们知道,任何数据类型都有一些专属于它们的方法,这些方法被存放在它们的原型链上,导致其他的数据类型不能使用专属方法。
- 如字符串的
str.substr()
方法,在数组中无法使用;而数组中的arr.reverse()
方法,在字符串中同样不能使用。如果发生这种情况,就会抛出错误。 - 这就需要,对函数传入的参数进行类型检查。
请看第一个例子:
function fn(arr) {
if (arr) {
arr.sort()
arr.reverse()
}
return arr
}
不安全的函数,任何非数组值都会报错。
function fn(arr) {
if (typeof arr.sort === 'function') {
arr.sort()
arr.reverse()
}
return arr
}
不够安全的函数,任何非数组值都会报错。如果传入的参数是一个带有sort()
方法的对象,那么就会出错。
function fn(arr) {
if (arr instanceof Array) {
arr.sort()
arr.reverse()
}
return arr
}
安全,传入的参数如果不是数组,则会被忽略。
请看第二个例子:
function getQueryString(url) {
const index = url.indexOf('?')
if (index > -1) {
return url.substring(index + 1)
}
return ''
}
不安全的函数,任何非字符串都会报错。如果传入的参数是数组,且数组中有'?'
,就会出错。
function getQueryString(url) {
if (typeof url === 'string') {
const index = url.indexOf('?')
if (index > -1) {
return url.substring(index + 1)
}
}
return ''
}
安全,传入任何不是字符串的值会被忽略。
总的来说,引用类型可以使用instanceof
,基本类型可以使用typeof
来检查数据类型。这样的数据类型检查是十分有必要的,尤其是作为暴露给公众的API时。
c. 通信错误
JavaScript 对服务端发起的任何一次通信都可能出错,如错误的url
,错误的数据格式。
从服务端接收的数据也可能出错,比如Ajax中定义了接收数据类型是json
,那么如果服务端响应的数据不是json
格式,则会出错。
结语
从红皮书第三版中读得此章节,受益匪浅。
码字不易,如果对你有帮助的话,请点一个赞吧