JavaScript 的错误处理

错误处理的核心首先要知道代码里会发生什么错误。由于 JavaScript 是松散类型的,不会验证函数的参数,因此错误只会在代码运行期间出现,一般来说,需要关注三种错误:类型转换错误,数据类型错误,通信错误

任何错误处理策略中终点就是确定错误是否致命。对于非致命错误可以根据下列条件确定:不影响用户的主要任务、只影响页面的一部分、可以恢复、重复相同操作可以消除错误。本质上非致命错误可以不关注,没有必要因为发生了非致命错误而向用户发出提示。致命错误可以通过下列条件来确定,应用程序根本无法继续运行、错误明显影响到了用户的主要操作、会导致其它连带错误。想要采取适当的措施,必须要知道 JavaScript 在什么情况下会发生致命错误。发生致命错误时,应立即给用户发送一条信息给,告诉用户无法再继续执行了。加入必须刷新页面才能让应用程序继续正常执行,就必须通知用户,同时给用户提供一个单机即可刷新页面的按钮。

1、认识错误类型

ECMA-262定义了下列 7 种错误类型,简单说明如下:

(1)Error:普通异常。通常与 throw 语句和 try/catch 语句一起使用。利用属性 name 可以声明或了解异常的类型,利用message 属性可以设置和读取异常的详细信息。

(2)EvalError:在不正确使用eval()方法时抛出。

(3)SyntaxError:抛出语法错误。

(4)RangeError:在数字超出合法范围时抛出。比如数组下标越界就会报这种错误。

(5)ReferenceError:在读取不存在的变量时抛出。比如没定义变量 a,后面却使用这个变量 a,就会报这种错。

(6)TypeError:当一个值的类型错误时抛出该异常。比如传递给函数的参数与预期的不符,就会报这种错误。

(7)URIError:由URL的编码和解码方法抛出。

利用不同的错误类型,可以获悉更多有关异常的信息,从而有助于对错误做出恰当的处理。如果想知道错误的类型,可以通过如下的 try-catch 语句的 catch 与中使用 instanceof 操作符:

try{
    test();
}catch(error){
    if(error instanceof TypeError){
        //处理类型错误
    }else if(error instanceof Referencesrror){
        //处理引用类型
    }else{
        //处理其他类型错误
    }
}

2、使用 try-catch

try-catch 语句,是 JavaScript 处理异常的一种标准方式。基本语法如下

try{
    //可能会导致错误的代码
}catch(error){
    //在错误发生时怎么处理
}

用户应把所有可能会抛出错误的代码都放在 try 语句块中,而把那些用于错误处理的代码放到 catch 块中。

try{
    a+b;
}catch (error){
    alert("非法的变量");
}

如果 try 块中的任何代码发生了错误,就会立即退出代码执行过程,然后接着执行 catch 块。此时,catch 块会接收到一个包含错误信息的对象。与在其他语言中不同的是,即使不使用这个错误对象,也要给它起个名字。

错误对象中包含的实际信息会因浏览器而异,但都有一个保存着错误消息的 message 属性。ECMA-262还规定了一个保存错误类型的 name 属性,当前所有浏览器都支持这个属性(Opera9之前的版本不支持这个属性)。因此,在发生错误时,就可以像下面这样实事求是地显示浏览器给出的消息。

try{
    a+b;
}catch (error){
    alert(error.message);
}

这个例子在向用户显示错误消息时,使用了错误对象的 message 属性,这个属性是唯一一个能够保证所有浏览器都支持的属性。

使用 try-catch 最适合处理那些无法控制的错误。假设在使用一个大型 JavaScript 库中的函数,该函数可能会有意无意地抛出一些错误,由于我们不能修改这个库的源代码,所以大可将对该函数的调用放在 try-catch 语句当中,万一有什么错误发生,也好恰当地处理它们。

在明明白白地知道自己的代码会发生错误时,再使用 try-catch 语句就不太合适了。例如,如果传递给函数的参数是字符串而非数值,就会造成函数出错,那么就应该先检查参数的类型,然后再决定如何去做。在这种情况下,不应使用 try-catch 语句。

3、使用 finally

finally 子句在 try-catch 语句中是可选的,但如果 finally 子句已经使用,则其代码无论如何都会执行。无论 try 或 catch 语句块中包含什么代码——甚至 return 语句,都不会阻止 finally 子句的执行。只要代码中包含 finally 子句,那么无论 try 还是 catch 语句块中的 return 语句都将被忽略。因此,在使用 finally 子句之前,一定要非常清楚想让代码怎么样。看下面这个函数:

function test(){
    try{
        return 2;
    }catch(error){
        return 1;
    }finally{
        return 0;
        console.log("不管错误发生 or 不发生错误我都会执行")
    }
}

这个函数在 try-catch 语句的每一部分都放了一条 return语句。表面上看,调用这个函数会返回 2,因为返回 2 的 return 语句位于 try 语句块中,而执行该语句又不会出错。可是,由于最后还有一个 finally 子句,结果就会导致该 return 语句被忽略,也就是说,调用这个函数只能返回0。如果把 finally 子句去掉,这个函数将返回2。

4、使用 throw

与 try-catch 语句相配的还有一个 throw 操作符,用于随时的主动抛出自定义错误。抛出错误时,必须要给 throw 操作符指定一个值,这个值是什么类型没有要求。比如下面的代码都是有效的。

throw 1;
throw "hi"
throw true;
throw {name:"js");

在遇到 throw 操作符时,代码会立即停止执行。仅当有 try-catch 语句捕获到被抛出的值时,代码才会继续执行。

throw new Error("抛出异常");
console.log("异常没有被try-catch,所以执行不到这里")

通过使用某种内置错误类型,可以更真实地模拟浏览器错误。每种错误类型的构造函数接收一个参数,即实际的错误消息。

throw new Error("Error");
throw new SyntaxError("SyntaxError");
throw new TypeError("TypeError");
throw new RangeError("RangeError");
throw new EvalError("EvalError");
throw new URIError("URIErrOT");
throw new ReferenceError("ReferenceError");

利用原型链还可以通过继承 Error 来创建自定义错误类型。此时,需要为新创建的错误类型指定 name 和 message 属性。

function CustomError(message){
    this.name ='CustomError';
    this.message = message;
}
CustomError.prototype = new Error();
throw new.CustomError("My message");

浏览器对待继承自 Error 的自定义错误类型,就像对待其他错误类型一样。如果要捕获自己抛出的错误并且把它与浏览器错误区别对待的话,创建自定义错误是很有用的。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值