JavaScript异常处理|try...catch

异常处理作用

JavaScript异常处理的作用是帮助开发者识别和处理运行时的错误和异常情况,确保程序在出现问题时能够优雅地降级或恢复,而不是导致整个应用崩溃或产生不可预测的行为。具体来说,异常处理可以做到以下几点:

  • 错误识别和定位: 异常处理允许开发者捕获和记录错误的详细信息,包括错误类型、发生位置和堆栈跟踪,从而有助于快速定位和解决问题。
  • 优雅的错误处理: 可以通过异常处理代码块(try-catch语句)捕获可能导致应用程序崩溃的异常,并提供备用方案或错误信息,以确保用户体验的连贯性和应用程序的稳定性。
  • 资源管理和释放: 在处理异常时,可以确保释放和清理资源(如文件、网络连接或内存),以避免资源泄漏或其他不良影响。
  • 异常消息提供: 可以向用户显示更加友好和信息丰富的错误消息,帮助用户理解发生了什么问题以及可能的解决方案。
  • 增强代码健壮性: 通过正确处理异常,可以提高代码的健壮性和稳定性,减少意外行为和难以调试的问题。

可以用 throw 语句抛出一个异常并且用 try...catch 语句捕获处理它。

throw语句

使用throw语句抛出一个异常。
你可以抛出任意表达式而不是特定一种类型的表达式。

throw "Error2"; // String type
throw 42; // Number type
throw true; // Boolean type
throw {
  toString: function () {
    return "I'm an object!";
  },
};

可以在抛出异常时声明一个对象。那样就可以在 catch 块中查询到对象的属性。

// 创建一个对象类型 UserException
function UserException(message) {
  this.message = message;
  this.name = "UserException";
}

// 使异常在作为字符串使用时转换为漂亮的字符串(例如通过错误控制台)
UserException.prototype.toString = function () {
  return this.name + ': "' + this.message + '"';
};

// 创建一个对象类型实例并抛出它
throw new UserException("Value too high");

try {
  // 抛出 UserException 异常
  throw new UserException("Value too high");
} catch (e) {
  // 捕获并处理异常
  console.log(e.toString()); // 输出:UserException: "Value too high"
}

try…catch语句

完整的应该是try...catch...finally 语句 。

1. try

try 块包含可能会抛出异常的代码。如果这些代码执行过程中抛出了异常,那么程序会立即跳到 catch 块执行。如果没有抛出异常,程序会继续执行 try 块中的代码,并跳过 catch 块。

2. catch

catch 块包含处理异常的代码。catch 块中的代码只有在 try 块中抛出异常时才会执行。如果 try 块没有抛出异常,catch 块将被跳过。

3. finally

finally 块中的代码无论 try 块是否抛出异常都会执行。finally 块通常用于清理资源,例如关闭文件、释放内存等。

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

UserException.prototype.toString = function () {
  return this.name + ': "' + this.message + '"';
};

try {
  // 可能抛出异常的代码
  throw new UserException("Value too high");
} catch (e) {
  // 处理异常
  console.log(e.toString()); // 输出:UserException: "Value too high"
} finally {
  // 无论是否发生异常,都会执行的代码
  console.log("Finally block executed.");
}

console.log("Code execution continues...");

运行结果:
image.png

finally块覆盖返回值

如果finally块返回一个值,该值会是整个try-catch-finally流程的返回值,不管在trycatch块中语句返回了什么:

function f() {
  try {
    console.log(0);
    throw "bogus";
  } catch (e) {
    console.log(1);
    return true; // this return statement is suspended
    // until finally block has completed
    console.log(2); // not reachable
  } finally {
    console.log(3);
    return false; // overwrites the previous "return"
    console.log(4); // not reachable
  }
  // "return false" is executed now
  console.log(5); // not reachable
}
f(); // console 0, 1, 3; returns false

嵌套 try…catch 语句

try...catch 语句是可以嵌套的,内部的 try 块可以没有 catch 块,但必须有一个 finally 块。如果内部的 try 块抛出异常且没有被内部的 catch 块捕获,那么外部的 catch 块将会被检查以捕获这个异常。

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

UserException.prototype.toString = function () {
  return this.name + ': "' + this.message + '"';
};

try {
  console.log("Outer try block starts.");
  
  try {
    console.log("Inner try block starts.");
    
    // 抛出一个异常
    throw new UserException("Value too high in inner try block");
    
    // 内部 try 块没有 catch 块,但有 finally 块
  } finally {
    console.log("Inner finally block executed.");
  }
  
} catch (e) {
  // 外部 catch 块捕获异常
  console.log("Caught in outer catch block: " + e.toString());
} finally {
  // 外部 finally 块总是会执行
  console.log("Outer finally block executed.");
}

console.log("Code execution continues...");

运行结果:
image.png

异常类型|标准异常

在 JavaScript 中,可以通过 throw 语句抛出任意类型的对象作为异常。然而,为了更好地处理错误和调试,通常使用标准的异常类型。

  • ECMAScript exceptions
    • ECMAScript(也称为 JavaScript)规范定义的一些标准的异常类型。
  • DOMException and DOMError
    • 与 DOM 操作相关的异常类型
    • DOMException: 当 DOM API 操作失败时抛出的异常。
    • DOMError: 这种类型的错误主要用于表示异步操作的失败,例如文件操作和 IndexedDB 操作。在现代浏览器中,DOMError 已经被废弃,推荐使用 DOMException

使用标准异常类型的好处

使用标准异常类型的好处包括:

  1. 可读性: 标准异常类型能够让代码的意图更加清晰,易于理解。
  2. 调试: 更丰富的错误信息能够帮助开发者更快地找到问题所在。
  3. 一致性: 使用标准的异常类型可以确保代码的一致性,使代码更加健壮。

例子|ReferenceError 错误

ReferenceError 是 JavaScript 中的一种标准异常类型,它在试图引用一个未定义的变量或对象时抛出。例如,当代码尝试使用一个不存在的变量或函数时,就会引发 ReferenceError 异常。

try {
  // 触发 ReferenceError 异常
  //console.log(nonExistentVariable); // 这个变量没有定义
  nonExistentFunction(); // 这个函数没有定义
} catch (e) {
  if (e instanceof ReferenceError) {
    console.log("Caught a ReferenceError: " + e.message);
  } else {
    console.log("Caught an unexpected error: " + e.message);
  }
} finally {
  console.log("Finally block executed.");
}

console.log("Code execution continues...");

使用Error对象

根据错误类型,可以用’name’和’message’获取更精炼的信息。

  • 'name’提供了常规的错误类(如 ‘DOMException’ 或 ‘Error’),
  • 'message’通常提供了一条从错误对象转换成字符串的简明信息。
function doSomethingErrorProne () {
  if (ourCodeMakesAMistake()) {
    throw (new Error('The message'));
  } else {
    doSomethingToGetAJavascriptError();
  }
}
....
try {
  doSomethingErrorProne();
}
catch (e) {
  console.log(e.name); // logs 'Error'
  console.log(e.message); // logs 'The message' or a JavaScript error message)
}

在 JavaScript 中,Error() 构造函数用于创建错误对象。错误对象包含关于发生错误的信息,例如错误消息和错误堆栈跟踪。可以使用 Error 构造函数创建自定义错误,或者扩展它来创建自定义错误类型。

try {
  throw new Error("Something went wrong!");
} catch (e) {
  console.log(e.name);    // 输出 "Error"
  console.log(e.message); // 输出 "Something went wrong!"
  console.log(e.stack);   // 输出堆栈跟踪信息
}

参考资料

流程控制与错误处理 - JavaScript | MDN
Error() 构造函数 - JavaScript | MDN

  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值