Skip to content

JavaScript 错误处理

try 语句允许你在代码块执行期间测试潜在的错误。

catch 语句允许你定义一个代码块,如果在 try 块中发生错误时执行。

throw 语句允许你创建自定义错误。最佳实践是抛出 Error 对象。

finally 语句允许你在 try 和 catch 之后执行代码,无论是否发生错误或错误是否被捕获。

执行 JavaScript 代码时,可能会发生各种错误。这些错误可以是语法错误、运行时错误或逻辑错误。

错误可能源于程序员失误、无效的用户输入、网络问题或其他意外情况:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Error Handling Example</title>
</head>
<body>
<p id="demo"></p>
<script>
try {
// 故意引发一个 ReferenceError:nonExistentFunction 未定义
nonExistentFunction("Welcome guest!");
} catch (error) {
const demoElement = document.getElementById("demo");
// 最佳实践是显示 error.message。你也可以记录 error.name 或完整的错误对象。
demoElement.textContent = `捕获到一个错误: ${error.message}`;
console.error(error); // 同时将完整错误记录到控制台进行调试
}
</script>
</body>
</html>

在上面的示例中,我们试图调用一个不存在的函数,导致了一个 ReferenceError(引用错误)。

catch 块“捕获”了这个错误,并执行代码来处理它,例如显示一个用户友好的消息。

try 语句定义了一个代码块,用于监视可能发生的错误。

catch 语句定义了一个代码块,如果 try 块中发生错误,则会执行该代码块。catch 块接收一个错误对象(通常命名为 err 或 error),其中包含错误的详细信息(例如,error.name,error.message)。

try 和 catch 语句总是成对出现:

try {
// 尝试执行的代码块
} catch (error) {
// 处理错误的代码块
// 'error' 是一个 Error 对象
}

常见的错误类型包括 Error、SyntaxError(语法错误)、ReferenceError(引用错误)、TypeError(类型错误)、RangeError(范围错误)和 URIError(URI 错误)。你可以检查 error.name 或使用 error instanceof TypeError 来针对不同的错误进行不同的处理。

当发生运行时错误时,JavaScript 通常会停止执行并“抛出”一个错误对象。

如果一个错误被抛出但未被 try…catch 块捕获,脚本将会终止(或者在浏览器中,当前的执行路径会停止,并在控制台记录一个错误)。

throw 语句允许你创建和抛出自己的自定义错误。

这在技术上被称为“抛出异常”。

虽然你可以抛出任何值(比如字符串或数字),但强烈建议抛出 Error 对象或继承自 Error 的对象。这可以提供更一致的错误信息(比如堆栈跟踪)。

// 旧写法(避免使用):
// throw "太大";
// throw 500;
// 现代最佳实践:
throw new Error("Something went wrong!"); // 抛出一个通用的 Error 对象
throw new TypeError("Invalid type provided."); // 抛出一个更具体的 TypeError 对象
// 对于更具体的错误,你可以创建自定义错误类:
class NetworkError extends Error {
constructor(message) {
super(message);
this.name = "NetworkError";
}
}
// throw new NetworkError("Connection failed."); // 抛出自定义的网络错误

结合使用 throw 与 try 和 catch,可以让你管理程序流程,并提供有意义的错误消息或恢复逻辑。

这个示例演示了如何验证用户输入。如果输入无效,将抛出一个 Error 对象并被捕获。

然后,catch 块会根据抛出的错误显示自定义的错误消息:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Input Validation</title>
</head>
<body>
<p>请在 5 到 10 之间输入一个数字:</p>
<input id="valueInput" type="text" /> <!-- 为了演示更广泛的验证,改为 type="text" -->
<button type="button" onclick="validateInput()">测试输入</button>
<p id="messageArea"></p>
<script>
function validateInput() {
const messageElement = document.getElementById("messageArea");
const inputElement = document.getElementById("valueInput");
messageElement.textContent = ""; // 清除之前的消息
try {
const inputValue = inputElement.value.trim(); // 获取输入值并去除首尾空白
if (inputValue === "") {
throw new Error("Input cannot be empty."); // 如果输入为空,抛出错误
}
const number = Number(inputValue); // 尝试将输入转换为数字
if (isNaN(number)) {
throw new Error("Input is not a valid number."); // 如果转换结果是 NaN,抛出错误
}
if (number < 5) {
throw new Error("Value is too low. Minimum is 5."); // 如果数字小于 5,抛出错误
}
if (number > 10) {
throw new Error("Value is too high. Maximum is 10."); // 如果数字大于 10,抛出错误
}
messageElement.textContent = "Input is valid!"; // 如果验证通过,显示成功消息
} catch (error) {
// 捕获到错误,显示错误消息
messageElement.textContent = `Error: ${error.message}`;
console.error("Validation failed:", error); // 在控制台记录详细错误
}
}
</script>
</body>
</html>

注意:HTML5 的输入属性,如 type=“number”、min、max 和 required,提供了内置的浏览器验证。JavaScript 验证可以补充这些功能,用于更复杂的规则或更好的用户反馈。

finally 语句定义了一个代码块,它将在 try 和 catch 块之后执行,无论是否发生错误或错误是否被捕获。

这对于清理任务非常有用,例如关闭文件、释放资源或重置状态。

try {
// 尝试执行的代码块
} catch (error) {
// 处理错误的代码块
} finally {
// 无论 try/catch 结果如何,都将执行的代码块
}

演示 finally 的示例:

function processData() {
const inputElement = document.getElementById("valueInput"); // 假设它存在于前一个示例中
const messageElement = document.getElementById("messageArea");
let result = "处理完成。";
try {
messageElement.textContent = "尝试处理...";
const value = parseInt(inputElement.value, 10); // 将输入值解析为整数
if (isNaN(value)) {
throw new Error("Cannot process non-numeric input."); // 如果不是数字,抛出错误
}
if (value < 0) {
throw new Error("Cannot process negative values."); // 如果是负数,抛出错误
}
// 模拟处理
result = `处理后的值: ${value * 2}`;
messageElement.textContent = result;
} catch (error) {
// 捕获错误并显示消息
messageElement.textContent = `处理过程中出错: ${error.message}`;
result = "处理失败。"; // 根据错误更新结果
} finally {
// 这个块总是会执行
console.log("清理阶段:操作完成。结果: " + result); // 记录操作结果
// 示例: inputElement.value = ""; // 尝试后清空输入字段
}
}
// 要测试,在用户输入后调用 processData()。确保 HTML 元素存在。

对于更高级的错误处理,尤其是异步操作,可以探索 Promise 和 async/await,它们有自己的错误处理机制(Promise 使用 .catch(),async/await 使用 try/catch)。

延伸阅读:MDN: try…catch