js错误处理

正文

try catch

在 JavaScript 中进行错误处理,最常见的方式就是使用try catch语句。将容易出错的代码段放入try块中,即可捕获错误,程序便至少不会因为一个错误而崩溃。

1. catch(error)

所有浏览器都支持error.message属性,它包含了错误的基本必要信息。而且在error对象中,基本也就该属性比较有用。所以,最好还是只用message属性。

2. finally

如果你加入了finally子句,那么它其中的代码无论如何都会执行,即使在trycatch中使用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
}

此函数的用意为拼接三个字符串,第三个字符串是可选的,所以要对第三个字符串进行检查。
如果没有传入第三个参数,则str3undefined,转化成布尔值是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格式,则会出错。

结语

从红皮书第三版中读得此章节,受益匪浅。
码字不易,如果对你有帮助的话,请点一个赞吧

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值