[关闭]
@wy 2017-09-25T22:33:07.000000Z 字数 3526 阅读 540

javascript错误处理类型

笔记


在写javascript的时候,调试错误必不可少,除了能够在浏览器中打印出来错误外,常常还需要知道错误的类型是什么,以便对症下药的纠错;也有时候,在自己封装的工具函数中,不传参或传入了错误类型的参数,也要适当的抛出一些错误以示警告;使用框架不正常情况下也会抛出错误,如果对错误一无所知,便无从下手调试。综合上述,了解错误的处理机制是多么必要,以下是笔者归纳总结,如有误之处,欢迎指出。

错误构造函数

javascript规范中总共有8中错误类型构造函数

其中两种做个特殊说明:

EvalError调用eval函数错误,已经弃用,为了向后兼容,低版本还可以使用。
InternalError 递归过深 抛出错误,多数浏览器未实现,属于非标准方法,生产环境禁用

继承关系

Error是错误的基类,其他类型都继承Error这个类,可以使用ES6中提供的Object.getPrototypeOf()来判断,一个类是否继承了另一个类。

  1. console.log(Object.getPrototypeOf(SyntaxError) === Error); // true
  2. console.log(Object.getPrototypeOf(TypeError) === Error); // true
  3. console.log(Object.getPrototypeOf(ReferenceError) === Error); // true
  4. console.log(Object.getPrototypeOf(RangeError) === Error); // true
  5. console.log(Object.getPrototypeOf(URIError) === Error); // true
  6. console.log(Object.getPrototypeOf(EvalError) === Error); // true

来聊一聊每一种错误类型的使用和出错的场景。

Error

通过Error的构造器可以创建一个错误对象。当运行时错误产生时,Error的实例对象会被抛出。

语法:new Error([message])

参数:

抛出错误

使用throw语句来抛出异常

  1. throw new Error('这里抛出的是错误信息')

运行后,会在控制台打印输出:

Uncaught Error: 这里抛出的是错误信息

注意: 使用throw抛出异常后,之后的代码不再执行。

捕获错误

可以通过try{}catch(){}语句来捕获到这个错误

  1. try{
  2. throw new Error('这里抛出的是错误信息')
  3. }catch(err){
  4. alert(err.name + ' '+ err.message)
  5. }

属性说明:
当使用new Error创建错误实例后,会有两个属性:

  1. let e = new Error('这里抛出的是错误信息');

name属性,为错误的类型,此时为Error
message属性,为错误的信息,此时为'这里抛出的是错误信息'

SyntaxError

解析过程语法错误,这种类型抛出的错误有很多,往往是书写时候造成的语法错误,例如:

  1. let n = 1\1; // Uncaught SyntaxError: Invalid or unexpected token
  2. let str = "hel"lo" // Uncaught SyntaxError: Unexpected identifier
  3. let 123Var = 'hi' // Uncaught SyntaxError: Invalid or unexpected token

语法错误有很多就不一一列举了,当在浏览器运行时,控制台会抛错,并且告知第几行,所以调试器来比较方便。但要读懂错误的类型为SyntaxError,以及后面的错误信息,这样方便改错。

TypeError

不属于有效类型。这种错误就是在给的不是需要的类型而导致无法操作,会抛出类型错误。

  1. let fn = 'hello';
  2. new fn;

抛出错误:

Uncaught TypeError: fn is not a constructor

  1. let obj = {};
  2. obj.fn()

抛出错误:

Uncaught TypeError: obj.fn is not a function

  1. function flatten(arr){
  2. if( !Array.isArray(arr) ){
  3. throw new TypeError('传入参数不是数组')
  4. }
  5. }
  6. flatten('test');

传入的参数不为数组时,抛出自定义的类型错误:

  1. Uncaught TypeError: 传入参数不是数组

ReferenceError

无效引用。

  1. console.log(a);

抛出错误

Uncaught ReferenceError: a is not defined

  1. let str = 'hello';
  2. if( str.charAt(0) = 'h' ){
  3. console.log('第一个字符为h');
  4. }

抛出错误:

Uncaught ReferenceError: Invalid left-hand side in assignment

RangeError

数值超出有效范围。在一些方法中,传入的数值必须在一定的范围内,否则会抛出超出范围的错误。

  1. let arr = new Array(-1)

抛出错误:

Uncaught RangeError: Invalid array length

  1. let str = 'hello';
  2. str.repeat(-1)

抛出错误:

Uncaught RangeError: Invalid count value

URIError

处理URI编码出错。函数参数不正确,主要是encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()、escape()和unescape()这六个函数。

例如:

  1. decodeURIComponent('%');
  2. decodeURI('%2')

抛出错误:

Uncaught URIError: URI malformed

自定义错误类型

有时候希望自定义错误类型,需要自定义一个构造函数,然后让原型继承继承Error.prototype即可。

  1. function MyErrorType(message){
  2. this.message = message || '错误';
  3. this.name = 'MyErrorType';
  4. this.stack = (new Error()).stack; // 错误位置和调用栈
  5. }
  6. MyErrorType.prototype = Object.create(Error.prototype);
  7. MyErrorType.prototype.constructor = MyErrorType;
  8. throw new MyErrorType('自定义错误类型抛出错误')

关于调用的错误栈信息

提供的错误的跟踪功能,以什么样的调用顺序,在哪个文件的哪一行捕获到这个错误。
例如以下调用:

  1. function trace() {
  2. try {
  3. throw new Error('myError');
  4. }
  5. catch(e) {
  6. console.log(e.stack);
  7. }
  8. }
  9. function b() {
  10. trace();
  11. }
  12. function a() {
  13. b(3, 4, '\n\n', undefined, {});
  14. }
  15. a('first call, firstarg');

错误信息为:

  1. Error: myError
  2. at trace (<Error.html>:3:14)
  3. at b (<Error.html>:10:6)
  4. at a (<Error.html>:13:6)
  5. at <Error.html>:15:4

以上为抛错的构造函数的总结,如有误之处欢迎扶正。
以上每一种错误场景并没有列出太多,如果你有新的错误信息发现,欢迎留言。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注