前端JavaScript 常见的报错及异常捕获。本文主要记录 JS 常见的一些错误类型、报错信息,分析其报错原因,并给予处理方法。并且将介绍几种捕获异常的方法。

常见的错误类型

  • RangeError标记一个错误,当设置的数值超出相应的范围触发。比如,new Array(-20)。
  • ReferenceError引用类型错误,当一个不存在的变量被引用时发生的错误。比如:console.log(a)。
  • SyntaxError语法错误
  • TypeError类型错误,表示值的类型非预期类型时发生的错误。

    RangeError

    ReferenceError 引用类型错误

当引用一个没有定义的变量时,抛出一个ReferenceError; 使用变量的时候,这个变量必须要声明,或者你可以确保它在你当前的脚本或作用域 (scope) 中可用。

  1. // 变量未声明
  2. console.log(a)

ReferenceError: “a” is not defined

解决方法,声明变量 a

SyntaxError 语法错误

这是最直接的 ‘你的代码写错了’,当代码中有非法的字符或者缺少必要的标识符号,比如减号 ( - ) 与连接符 ( – ) ,或者是英文双引号 ( “ ) 与中文双引号 ( “ )误用。

🙌 🌰:

  1. // 遗漏的字符
  2. let str = 'string;
  3. let colors = ['#000', #333', '#666'];
  4. // 使用特殊字符
  5. let str1 = 'string";
  6. let str2 = 5#5;
  7. // 错配字符(使用中文引号字符)
  8. let str3 = ‘string’;

处理办法

睁大眼睛仔细检查,看是否有特殊字符或者是否遗漏一些字符。

TypeError 类型错误


异常调试及捕获

try catch 异常处理

JavaScript 同样的内置了 try catch 这套现代的 异常处理机制,很方便我们在编程中,提前对那些有可能遇见到的错误进行处理。ECMA-262 第 3 版中引入了 try-catch 语句,作为 JavaScript 中处理异常的一种标准方式,基本的语法如下所示。这和 Java 中的 try-catch 语句是完全相同的。

  1. try {
  2. // 可能会导致错误的代码
  3. } catch (error) {
  4. // 在错误发生时怎么处理
  5. }

如果 try 块中的任何代码发生了错误,就会立即退出代码执行过程,然后执行 catch 块。此时 catch 块会接收到一个包含错误信息的对象,这个对象中包含的信息因浏览器而异,但共同的是有一个保存着错误信息的 message 属性。

🙌🌰

  1. try { // 尝试执行
  2. b = a + 1
  3. } catch (e) { // 出现错误,对错误进行捕获
  4. console.log('当前错误信息:' + e.message)
  5. }

image.png

finally

try catch 语法的补充。

  1. try { // 尝试执行
  2. b = a + 1
  3. } catch (e) { // 出现错误,对错误进行捕获
  4. console.log('当前错误信息:' + e.message)
  5. } finally {
  6. console.log(1) // 无论 try 成功还是失败,finally 都会被执行
  7. }

finally 子句在 try-catch 语句中是可选的,但是 finally 子句一经使用,其代码无论如何都会执行。换句话说,try 语句块中代码全部正常执行,finally 子句会执行;如果因为出错执行了 catch 语句,finally 子句照样会执行。只要代码中包含 finally 子句,则无论 try 或 catch 语句中包含什么代码——甚至是 return 语句,都不会阻止 finally 子句执行。来看下面函数的执行结果:

  1. function testFinally {
  2. try {
  3. return "出去玩";
  4. } catch (error) {
  5. return "看电视";
  6. } finally {
  7. return "做作业";
  8. }
  9. return "睡觉";
  10. }

表面上调用这个函数会返回 “出去玩”,因为返回 “出去玩” 的语句位于 try 语句块中,而执行此语句又不会出错。实际上返回 “做作业”,因为最后还有 finally 子句,结果就会导致 try 块里的 return 语句被忽略,也就是说调用的结果只能返回 “做作业”。如果把 finally 语句拿掉,这个函数将返回 “出去玩”。因此,在使用 finally 子句之前,一定要非常清楚你想让代码怎么样。(思考一下如果 catch 块和 finally 块都抛出异常,catch 块的异常是否能抛出)

查看错误类型

通过 catch 捕获到的错误,是有多种类型的,每种类型描述了相应的错误问题,可以通过 instanceof 查看错误类型。

  1. try {
  2. b = a + 1
  3. } catch (e) {
  4. console.log(e instanceof Error) // true
  5. console.log(e instanceof ReferenceError) // true | 引用错误
  6. console.log(e instanceof SyntaxError) // false | 语法错误
  7. }
  8. /*
  9. 所有错误类型都是 Error 的派生类
  10. Error
  11. +-- SyntaxError
  12. +-- ReferenceError
  13. +-- RangeError
  14. +-- TypeError
  15. +-- URIError
  16. +-- EvalError
  17. */

throw 抛出错误

我们也能自定义错误,然后让解释器报错。

  1. try {
  2. throw new TypeError('1') // 抛出一个类型错误
  3. } catch (e) {
  4. console.log(e) // 捕获 | TypeError: 1
  5. }
  1. function getUserName(name) {
  2. if(!name) throw new Error('用户名无效');
  3. return name;
  4. }
  5. getUserName()

异步与错误

catch 没办法捕获到异步执行抛出的错误。

  1. try {
  2. setTimeout(() => {
  3. throw new Error('1')
  4. }, 1000)
  5. } catch (e) {
  6. // 无法捕获 new Error('1')
  7. }

Promise 异常处理

Promise执行中,本身自带try…catch的异常处理,出错时,将错误Rejact函数。

  1. new Promise((resolve, reject) => {
  2. throw new Error('error!');
  3. }).catch(alert);

console 查看信息

使用console.log打印javaScript的值

  1. let value = '你最棒了,点个赞呗!'
  2. console.log(value)

debugger 断点调试

debugger 断点调试,用于停止执行 JavaScript,并调用调试函数。

  1. let value = 15;
  2. debugger
  3. document.querySelector('body').innerHTML = '你最棒了,点个赞呗!'

window.onerror 异常捕获

当 JS 运行时错误发生时,window 会触发一个 ErrorEvent 接口的 error 事件,并执行window.onerror()。

  1. /**
  2. * @param {String} message 错误信息
  3. * @param {String} source 出错文件
  4. * @param {Number} lineno 行号
  5. * @param {Number} colno 列号
  6. * @param {Object} error Error对象(对象)
  7. */
  8. window.onerror = function (message, source, lineno, colno, error) {
  9. console.log("捕获到异常:", { message, source, lineno, colno, error });
  10. };

同步错误可以捕获到,但是,请注意 window.error 无法捕获静态资源异常和 JS 代码错误。