Error,Error,到底什么是Error

简介: 总所周知,当系统运行出现错误的时候,就会抛出一个 Error ,那么这个 Error 是什么?它是怎么来的?它又是怎么被抛出的?它又是怎么被捕获的?这些问题,我们一起来探讨一下。

总所周知,当系统运行出现错误的时候,就会抛出一个Error,那么这个Error是什么?它是怎么来的?它又是怎么被抛出的?它又是怎么被捕获的?这些问题,我们一起来探讨一下。

1. Error

Error是一个对象,它是浏览器提供的一个内置对象,它的实例属性主要有:

  • name:错误的名称,比如TypeErrorReferenceError
  • message:错误的描述信息
  • cause:错误的原因
  • stack:错误的堆栈信息,非标准属性
  • fileName:错误发生的文件名,非标准属性,Mozilla提供
  • lineNumber:错误发生的行号,非标准属性,Mozilla提供
  • columnNumber:错误发生的列号,非标准属性,Mozilla提供
  • line:错误发生的行的内容,非标准属性,Mozilla提供

静态属性:

  • Error.captureStackTrace:捕获错误的堆栈信息,非标准属性,V8提供
  • Error.stackTraceLimit:设置错误堆栈信息的最大长度,非标准属性,V8提供

静态方法:

  • Error.captureStackTrace():捕获错误的堆栈信息,非标准方法,V8提供
  • Error.prepareStackTrace():格式化错误堆栈
  • Error.stackTraceLimit:设置错误堆栈信息的最大长度,非标准方法,V8提供

实例方法:

  • error.toString():返回错误的字符串表示,覆盖了Object.prototype.toString()方法

2. Error的创建

Error对象是通过new关键字来创建的,它的构造函数有三种形式:

  • new Error(message)
  • new Error(message, { cause })
  • new Error(message, fileName, lineNumber)

其中,message是错误的描述信息,cause是错误的原因,它们都是可选的。

目前只有messagecause两个参数是确定的;

name属性是不确定的,它的值取决于错误的类型,比如TypeErrorReferenceError等;

stack属性也是不确定的,它的值取决于错误的堆栈信息。

其他的属性,比如fileNamelineNumbercolumnNumberline等,他们是由Mozilla提供的,它们的值取决于浏览器的实现。

3. Error的抛出

Error对象是通过throw关键字来抛出的,它的抛出形式有两种:

  • throw new Error()
  • throw 'error message'

第一种形式是抛出一个Error对象,第二种形式是抛出一个字符串,它们的区别是:

* 第一种形式抛出的是一个`Error`对象,它拥有`error`对象的所有属性和方法,比如`name`,`message`,`stack`等;
* 第二种形式抛出的是一个字符串,它只有`message`属性,没有`name`属性,也没有`stack`属性。

通常情况下,我们都是抛出一个Error对象,而不是抛出一个字符串。

4. Error的捕获

Error对象是通过try...catch关键字来捕获的,它的捕获形式有两种:

  • try...catch
  • try...catch...finally
try {
   
  // ...
} catch (error) {
   
  // ...
} finally {
   
  // ...
}

关于catch语句可以省略遗产捕获的参数,或者不写catch,但是并不是所有的浏览器都支持,比如IE浏览器就不支持。

try {
   
    // ...
} catch {
   
    // ...
} finally {
   
    // ...
}

try {
   
    // ...
} finally {
   
    // ...
}

5. 自定义Error

es6之前,Error如果要实现自定义的错误,只能通过prototype来实现,比如:

function MyError(message, fileName, lineNumber) {
   
    var instance = new Error(message, fileName, lineNumber);
    Object.setPrototypeOf(instance, CustomError.prototype);
    if (Error.captureStackTrace) {
   
        Error.captureStackTrace(instance, CustomError);
    }
    return instance;
}

Object.setPrototypeOf(MyError.prototype, Error.prototype);

Object.setPrototypeOf(MyError, Error);

MyError.prototype.name = 'MyError';

try {
   
    throw new MyError('error message');
} catch(e) {
   
    console.error(e.name); // MyError
    console.error(e.message); // error message
}

es6之后,Error可以通过class来实现自定义的错误,比如:

class MyError extends Error {
   
    constructor(message) {
   
        super(message);
        this.name = 'MyError';

        if (Error.captureStackTrace) {
   
            Error.captureStackTrace(this, MyError);
        }
    }
}

try {
   
    throw new MyError('baz', 'error message');
} catch(e) {
   
    console.error(e.name); // MyError
    console.error(e.message); // error message
}

6. 浏览器内置的Error

在浏览器的Error类型中,Error是一个基类,它的子类有EvalErrorRangeErrorReferenceErrorSyntaxErrorTypeErrorURIError等。

try {
   
    throw new EvalError('error message');
} catch(e) {
   
    console.error(e.name); // EvalError
    console.error(e.message); // error message
}

它们都是继承自Error的,所以它们都拥有Error的所有属性和方法,它们之间的区别是,在不同的情况下,会抛出不同的错误。

它们并没有太多区别,只是用于提示用户在不同的情况下,用于描述错误的信息,使用户更好的理解错误的原因。

本质上它们都是Error的子类,所以它们都可以通过instanceof来判断,比如:

try {
   
    throw new EvalError('error message');
} catch(e) {
   
    console.error(e instanceof Error); // true
    console.error(e instanceof EvalError); // true
}

结语

ErrorJavaScript中非常重要的一个类型,它用于描述错误的信息,使用户更好的理解错误的原因,同时也是开发者非常头疼的一个类型,愿开发的过程中无Error

目录
相关文章
|
11月前
|
Java 数据库连接 数据库
ERROR 11848
ERROR 11848
142 1
|
10月前
|
前端开发 JavaScript
Uncaught (in promise) Error: Request failed with status code 500
Uncaught (in promise) Error: Request failed with status code 500
459 0
|
12月前
使用errors.Wrapf()代替log.Error()
使用errors.Wrapf()代替log.Error()
49 0
|
关系型数据库 MySQL C++
Error:fatal error C1010: unexpected end of file while looking for precompiled head
Error:fatal error C1010: unexpected end of file while looking for precompiled head
107 0
|
关系型数据库 MySQL
把log_error_verbosity设置为3,调试连接问题ERROR 2003 (HY000):ERROR 1045 (28000):
mysql 8里面使用global log_error_verbosity控制日志记录的详细程度
SignTool Error: An error occurred while attempting/Error information: “SignerTimeStamp() failed.“
SignTool Error: An error occurred while attempting/Error information: “SignerTimeStamp() failed.“
139 0
C中error的使用
C中error的使用
78 0
|
数据库 C++
VS错误的解决解决:LINK fatal error LNK1000: Internal error during IncrBuildImage
VS错误的解决解决:LINK fatal error LNK1000: Internal error during IncrBuildImage
231 0
gittalk Error: Not Found.
gittalk Error: Not Found.
248 0
gittalk Error: Not Found.