JavaScript throw 关键字
最后修改于 2025 年 4 月 16 日
在本文中,我们将展示如何使用 JavaScript 中的 throw 关键字来处理错误。
throw 关键字
throw 关键字用于在 JavaScript 中创建自定义错误。 当它被执行时,它会停止当前函数的执行并将控制权传递给调用堆栈中的第一个 catch 块。 如果不存在 catch 块,程序将终止。
您可以抛出任何表达式,但最佳实践是抛出 Error 对象或继承自 Error 的对象。 这提供了一致的错误处理和对堆栈跟踪的访问。 throw 语句通常与 try-catch 块一起使用,以进行适当的错误处理。
与某些语言不同,JavaScript 允许抛出任何值 - 字符串、数字、对象。 但是,建议使用 Error 对象以获得更好的调试效果。 throw 语句对于创建健壮的、容错的代码至关重要。
使用字符串的基本 throw
最简单的例子是抛出一个字符串作为错误。
try {
throw "An error occurred";
} catch (e) {
console.log("Caught:", e);
}
这演示了抛出一个原始字符串值。 虽然可行,但不建议在生产代码中使用。 catch 块接收抛出的字符串并将其记录下来。 这展示了基本的 throw-catch 机制。
$ node main.js Caught: An error occurred
抛出 Error 对象
一个更好的做法是抛出一个 Error 对象。
try {
throw new Error("Something went wrong");
} catch (e) {
console.log("Error name:", e.name);
console.log("Error message:", e.message);
console.log("Stack trace:", e.stack);
}
Error 对象比原始值提供更多信息。 它们包含用于调试的堆栈跟踪。 此示例显示了访问错误的属性。 Error 构造函数接受一条描述错误的 message。
$ node main.js
Error name: Error
Error message: Something went wrong
Stack trace: Error: Something went wrong
at Object.<anonymous> (...)
自定义错误类
您可以通过扩展 Error 来创建自定义错误类。
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
try {
throw new ValidationError("Invalid input");
} catch (e) {
if (e instanceof ValidationError) {
console.log("Custom error caught:", e.name, e.message);
}
}
这为验证失败创建了一个专门的错误类型。 自定义错误允许更具体的错误处理。 instanceof 检查验证了错误类型。 这种模式对于创建特定于领域的错误层次结构很有用。
$ node main.js Custom error caught: ValidationError Invalid input
在函数中抛出
函数可以抛出错误,这些错误会被调用代码捕获。
function divide(a, b) {
if (b === 0) {
throw new Error("Division by zero");
}
return a / b;
}
try {
console.log(divide(10, 0));
} catch (e) {
console.log("Error:", e.message);
}
这展示了在检测到无效输入时从函数抛出错误。 调用代码处理潜在的错误。 这是输入验证的常见模式。 错误会在调用堆栈中传播,直到被捕获。
$ node main.js Error: Division by zero
重新抛出错误
您可以捕获一个错误,部分处理它,然后重新抛出它。
function processData(data) {
if (!data) {
throw new Error("No data provided");
}
// Process data...
}
try {
try {
processData(null);
} catch (e) {
console.log("Logging error:", e.message);
throw e; // Rethrow
}
} catch (e) {
console.log("Outer catch:", e.message);
}
这演示了在多个级别上的错误处理。 内部 catch 在重新抛出错误之前记录该错误。 外部 catch 处理重新抛出的错误。 当不同的层需要以不同的方式处理错误时,这很有用。
$ node main.js Logging error: No data provided Outer catch: No data provided
抛出非 Error 对象
虽然不推荐,但您可以抛出任何 JavaScript 值。
try {
throw {
code: 404,
message: "Not Found",
timestamp: new Date()
};
} catch (e) {
console.log(`Error ${e.code} at ${e.timestamp}: ${e.message}`);
}
这抛出一个自定义对象而不是一个 Error。 虽然灵活,但这种方法缺少堆栈跟踪和标准错误属性。 catch 块必须知道对象的结构。 这种模式有时用于 API 错误响应。
$ node main.js Error 404 at Wed Apr 16 2025 12:00:00 GMT+0000: Not Found
实际用例:输入验证
这是一个使用 throw 进行输入验证的实际例子。
function registerUser(user) {
if (!user.name) {
throw new Error("Name is required");
}
if (user.age < 18) {
throw new Error("User must be 18 or older");
}
// Registration logic...
console.log("User registered:", user.name);
}
try {
registerUser({ name: "John", age: 16 });
} catch (e) {
console.log("Registration failed:", e.message);
}
这在处理之前验证用户输入。 每个验证失败都会抛出一个描述性错误。 调用代码优雅地处理任何验证错误。 这种模式确保无效数据不会在应用程序中进一步进行。
$ node main.js Registration failed: User must be 18 or older
来源
在本文中,我们已经演示了如何使用 throw 关键字来处理 JavaScript 中的错误。