良好的错误处理机制可以让用户得到及时的提醒,所以让我们来看看 JavaScript 提供了哪些针对错误处理的工具和方法吧O(∩_∩)O~
1 try-catch 语句ECMA-262 第 3 版引入了 try-catch 语句,这时 JavaScript 处理异常的标准方式:
try{ //可能会导致错误的代码 } catch (error){ //错误处理 }
如果 try 块中的代码发生了错误,会立即执行 catch 块的代码。 catch 块有一个包含错误信息的对象,它有一个 message 属性,表示的是浏览器给出的错误消息:
<script type="text/javascript"> try { window.someNonexistenceFunction(); } catch (error) { console.log(error.message); } </script>
message 属性是所有的浏览器都支持的属性,所以在跨浏览器编程中,最好只使用这个属性。
1.1 finally 子句finally 子句是可选的,如果使用了 finally 子句,里面包含的代码是绝对会被执行的!甚至连 return 语句都无法阻止它被执行:
<script type="text/javascript"> function testFinally() { try { return 2; } catch (error) { return 1; } finally { return 0; } } console.log(testFinally());//0 </script>
IE7 及更早的版本有一个 bug:除非有 catch 子句,否则 finally 中的代码永远不会被执行!IE8 修复了这个 bug。
注意:只要在代码中使用了 finally 子句,那么不管 return 放在 try 还是 catch 语句中,都会被忽略!
1.2 错误类型当错误发生时,会抛出相应类型的错误对象。ECMA-262 定义了 7 种错误类型:
Error
EvalError
RangeError
ReferenceError
SyntaxError
TypeError
URIError
1.2.1 Error
Error 是基类型,即其他的错误类型都是从 Error 继承来的。可以利用 Error 来自定义错误类型。
1.2.2 EvalError
EvalError 是在使用 eval() 函数发生异常时被抛出。怎么才算是异常呢?如果没有把 eval() 当作函数来使用,就会抛出 EvalError:
new eval();//抛出 EvalError eval = foo;//抛出 EvalError
实际开发中很少这样使用 eval() 函数的(除非脑袋秀逗了O(∩_∩)O~),所以很少会遇到 EvalError。
1.2.3 RangeError
RangeError 会在数值超出规定范围时被抛出。比如在定义数组时,指定了数组不支持的数组项数,就会抛出这个错误:
var item1 = new Array(-20);//抛出 RangeError var item1 = new Array(Number.MAX_VALUE);//抛出 RangeError
1.2.4 ReferenceError
找不到对象时,会抛出 ReferenceError(这就是浏览器的知名的 “object expected” 错误)。一般在访问不存在的变量时,会抛出这个错误:
var obj = x;//x 还未被声明,所以抛出 ReferenceError
1.2.5 SyntaxError
如果把带着错误语法的字符串传入 eval() 函数时,就会抛出 SyntaxError:
eval("a ++ b");//抛出 SyntaxError
在 eval() 函数之外的语法错误,会导致 JavaScript 立即停止执行,所以不会抛出这个错误!
1.2.6 TypeError
如果变量中保存着意外的类型,或者访问不存在的方式时,就会抛出 TypeError。这个错误比较常见:
var o = new 10;//抛出 TypeError alert("name" in true);//抛出 TypeError Function.prototype.toString.call("name");//抛出 TypeError
如果传递给函数的参数类型与预期类型不符,也会抛出这个错误。
1.2.7 URIError
使用 encodeURI() 或者 decodeURI() 时,URI 的格式不正确,就会抛出 URIError 错误。一般很少发生,因为这两个函数有着非常高的容错性O(∩_∩)O~
可以针对这些错误类型进行恰当的处理:
try{ someFunction(); } catch (error){ if (error instanceof TypeError){ //处理类型错误 } ... }
因为包含在 message 中的消息会因浏览器而异,所以在跨浏览器编程中,最好直接检查这些错误类型。
1.3 合理使用 try-catchtry-catch 最适合用于那些我们无法控制的错误,比如使用了一个开源库中的函数,而我们无法修改源代码的情况。
而对于自定义的函数,验证函数参数类型是否合法的情况,就不应该使用 try-catch,因为这个函数是我们可以修改的,在使用参数前先进行验证才是正途。
2 抛出错误throw 操作符可以抛出自定义的错误,必须要指定一个值,这个值可以是任意类型。代码在遇到 throw 操作符时,会立即停止执行。只有在 try-catch 语句捕获到被抛出的值时,才会继续执行。
通过使用之前说过的内置错误类型,可以模拟浏览器错误。这些错误类型的构造函数都接收一个参数,即实际的错误消息:
throw new Error("Something bad happened.");
最常使用这些错误类型来创建自定义的错误消息:Error、RangeError、ReferenceError 和 TypeError。
也可以利用原型链,通过继承 Error 来创建自定义消息。比如,这里为新创建的错误类型指定了 name 和 message 属性: