JS错误处理

1、使用try catch语句

try {
  window.someNonexistentFunction();
} catch (error){
  console.log(error.message);
}

如果 try 块中有代码发生错误,代码会立即退出执行,并跳到 catch 块中。
错误对象中暴露的实际信息因浏览器而异,但至少包含保存错误消息的message属性。
message 属性是唯一一个在 IE、 Firefox、 Safari、
Chrome 和 Opera 中都有的属性,尽管每个浏览器添加了其他属性。 IE 添加了 description 属性(其值
始终等于 message)和 number 属性(它包含内部错误号)。 Firefox 添加了 fileName、 lineNumber
和 stack(包含栈跟踪信息)属性。 Safari 添加了 line(行号)、 sourceId(内部错误号)和 sourceURL
属性。同样,为保证跨浏览器兼容,最好只依赖 message 属性。

  • finally 子句
    try 或 catch 块无法阻止 finally 块执行,包括 return 语句
function testFinally(){
  try {
    return 2;
  } catch (error){
    return 1;
  } finally {
    return 0;
  }
}

无论什么情况下调用该函数都会返回 0。如果去掉 finally 子句,该函数会返回 2。如果写出finally 子句, catch 块就成了可选的(它们两者中只有一个是必需的)
2、错误类型

  • Error
  • InternalError 类型的错误会在底层 JavaScript 引擎抛出异常时由浏览器抛出。例如,递归过多导
    致了栈溢出。这个类型并不是代码中通常要处理的错误,如果真发生了这种错误,很可能代码哪里弄错
    了或者有危险了。
  • EvalError 类型的错误会在使用 eval()函数发生异常时抛出
  • RangeError 错误会在数值越界时抛出。例如,定义数组时如果设置了并不支持的长度,如-20 或Number.MAX_VALUE,就会报告该错误
  • ReferenceError会在找不到对象时发生。(这就是著名的"object expected"浏览器错误的原因。)这种错误经常是由访问不存在的变量而导致的,比如:
let obj = x; // 在 x 没有声明时会抛出 ReferenceError
  • SyntaxError 经常在给 eval()传入的字符串包含 JavaScript 语法错误时发生,比如:
eval("a ++ b"); // 抛出 SyntaxError
  • TypeError 在 JavaScript 中很常见,主要发生在变量不是预期类型,或者访问不存在的方法时。很
    多原因可能导致这种错误,尤其是在使用类型特定的操作而变量类型不对时。下面是几个例子
let o = new 10; // 抛出 TypeError
console.log("name" in true); // 抛出 TypeError
Function.prototype.toString.call("name"); // 抛出 TypeError
  • URIError

Error 是基类型,其他错误类型继承该类型。因此,所有错误类型都共享相同的属性(所有错误对象上的方法都是这个默认类型定义的方法)。浏览器很少会抛出 Error 类型的错误,该类型主要用于开发者抛出自定义错误。
3、抛出错误
throw 操作符必须有一个值,但值的类型不限。下面这些代码都是有效的:

throw 12345;
throw "Hello world!";
throw true;
throw { name: "JavaScript" };

使用 throw 操作符时,代码立即停止执行,除非 try/catch 语句捕获了抛出的值。
可以通过内置的错误类型来模拟浏览器错误。每种错误类型的构造函数都只接收一个参数,就是错误消息。下面看一个例子:

throw new Error("Something bad happened.");

浏览器会像处理自己生成的错误一样来处理这个自定义错误。换句话说,浏览器会像通常一样报告这个错误,最终显示这个自定义错误。

此外,通过继承 Error(第 6 章介绍过继承)也可以创建自定义的错误类型。创建自定义错误类型
时,需要提供 name 属性和 message 属性,比如:

class CustomError extends Error {
  constructor(message) {
    super(message);
    this.name = "CustomError";
    this.message = message;
  }
}
throw new CustomError("My message");

继承 Error 的自定义错误类型会被浏览器当成其他内置错误类型。自定义错误类型有助于在捕获
错误时更准确地区分错误。

断言函数,console.assert()可用于代替多个 if 语句,同时也是记录错误的好地方。

function divide(num1, num2) {
  console.assert(typeof num1 == "number" && typeof num2 == "number",
  "divide(): Both arguments must be numbers.");
  return num1 / num2;
}

相当于:
function divide(num1, num2) {
  if (typeof num1 != "number" || typeof num2 != "number"){
    throw new Error("divide(): Both arguments must be numbers.");
  }
  return num1 / num2;
}

4、error事件
任何没有被 try/catch 语句处理的错误都会在 window 对象上触发 error 事件。
在 onerror 事件处理程序中,任何浏览器都不会传入 event 对象。相反,会传入 3 个参数:错误消息、发生错误的 URL 和行号。
在任何错误发生时,无论是否是浏览器生成的,都会触发 error 事件并执行这个事件处理程序。可以返回 false 来阻止浏览器默认报告错误的行为,如下所示:

window.onerror = (message, url, line) => {
  console.log(message);
  return false;
};

通过返回 false,这个函数实际上就变成了整个文档的 try/catch 语句,可以捕获所有未处理的运行时错误。这个事件处理程序应该是处理浏览器报告错误的最后一道防线。理想情况下,最好永远不要用到。适当使用 try/catch 语句意味着不会有错误到达浏览器这个层次,因此也就不会触发 error事件。

图片也支持 error 事件。任何时候,如果图片 src 属性中的 URL 没有返回可识别的图片格式,就会触发 error 事件。这个事件遵循 DOM 格式,返回一个以图片为目标的 event 对象。

const image = new Image();
image.addEventListener("load", (event) => {
  console.log("Image loaded!");
});
image.addEventListener("error", (event) => {
  console.log("Image not loaded!");
});
image.src = "doesnotexist.gif"; // 不存在,资源会加载失败

你可能感兴趣的:(JS错误处理)