异常处理作用
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...");
运行结果:
finally
块覆盖返回值
如果finally
块返回一个值,该值会是整个try-catch-finally
流程的返回值,不管在try
和catch
块中语句返回了什么:
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...");
运行结果:
异常类型|标准异常
在 JavaScript 中,可以通过 throw
语句抛出任意类型的对象作为异常。然而,为了更好地处理错误和调试,通常使用标准的异常类型。
- ECMAScript exceptions
- ECMAScript(也称为 JavaScript)规范定义的一些标准的异常类型。
- DOMException and DOMError
- 与 DOM 操作相关的异常类型
- DOMException: 当 DOM API 操作失败时抛出的异常。
DOMError: 这种类型的错误主要用于表示异步操作的失败,例如文件操作和 IndexedDB 操作。在现代浏览器中,DOMError
已经被废弃,推荐使用DOMException
。
使用标准异常类型的好处
使用标准异常类型的好处包括:
- 可读性: 标准异常类型能够让代码的意图更加清晰,易于理解。
- 调试: 更丰富的错误信息能够帮助开发者更快地找到问题所在。
- 一致性: 使用标准的异常类型可以确保代码的一致性,使代码更加健壮。
例子|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