Skip to main content

错误处理

JavaScript 解析或运行时,一旦发生错误,引擎就会抛出一个错误对象。JavaScript 原生提供 Error 构造函数,所有抛出的错误都是这个构造函数的实例。该实例主要有以下几个属性:

  • message:错误提示信息
  • name:错误名称(非标准属性)
  • stack:错误的堆栈(非标准属性)

原生错误类型

  • syntaxError。解析代码时发生的语法错误
  • ReferenceError。引用一个不存在的变量
  • RangeError。一个值超出有效范围时发生的错误。主要有几种情况,一是数组长度为负数,二是 Number 对象的方法参数超出范围,以及函数堆栈超过最大值
  • TypeError。变量或参数不是预期类型
  • EvalError。eval 函数没有被正确执行
  • URIError。 URI 相关函数的参数不正确时抛出的错误

自定义错误

function MyError(message = "myError") {
this.message = message;
this.name = "MyError";
}

MyError.prototype = new Error();
MyError.prototype.constructor = MyError;

// ...
new MyError("自定义错误");

抛出错误

可以通过 throw 语句中断程序执行,抛出一个错误。throw 可以抛出任意值

捕获错误

同步错误

  • try-catch。能捕获常规运行时错误,无法捕获语法和异步错误(可以捕获 await 语句的错误)
  • window.onerror。当 JS 运行时错误发生时,window 会触发一个 ErrorEvent 接口的 error 事件

可以这么理解,onerror 主要是来全局捕获预料之外的错误,而 try-catch 则是用来在可预见情况下捕获错误

异步错误

涉及异步事件和静态资源加载

  • 在 promise 中使用 catch 捕获异步错误,以及可以用 try-catch 可以捕获 await 错误
  • window.addEventListener('unhandledrejection', ()=>{})。全局捕获 promise 未 catch 的错误
  • window.addEventListener('error', ()=>{}, true)。当一项资源(如图片)加载失败,加载资源的元素会触发一个 Event 接口的 error 事件,并执行该元素上的 onerror() 处理函数,这些 error 事件不会向上冒泡到 window,但可以被捕获
  • new Image().onerror()。捕获 new Image() 异常

为什么 try-catch 可以捕获 await 错误?

因为 await 会把 rejected promise 转变成了一个 throw,参考 https://www.zhihu.com/question/522726685