JavaScript: JavaScript 错误与调试
最后更新:2026-10-13
写代码不出 bug 是不可能的——连 JavaScript 的创造者都在 10 天里写出了 typeof null === "object" 这种 bug。所以,学会找 bug 和处理错误比学会写代码更重要。
1. 错误处理与调试技巧
| 错误类型 | 原因 | 示例 |
|---|---|---|
SyntaxError |
语法写错了 | if (true { 括号不匹配 |
ReferenceError |
访问不存在的变量 | console.log(notExist) |
TypeError |
对错误类型执行操作 | undefined.toString() |
RangeError |
值超出有效范围 | new Array(-1) |
SyntaxError 在代码执行前就会被发现(编译阶段),其余三种是运行时错误。
(2) try...catch...finally
用 try...catch 捕获运行时错误,防止程序崩溃:
HTML
<script>
try {
const data = JSON.parse('{bad json}');
} catch (error) {
console.log("解析失败:", error.message);
} finally {
console.log("清理工作");
}
</script>
error.message:错误描述error.name:错误类型名
(3) throw 手动抛出错误
try...catch 只能捕获运行时错误,但业务逻辑的错误需要你自己抛:
HTML
<script>
function setAge(age) {
if (typeof age !== "number" || age < 0) {
throw new Error("年龄必须是正数");
}
console.log("年龄设置为:" + age);
}
try {
setAge(-5);
} catch (e) {
console.log(e.message);
}
</script>
throw 可以抛出任何值,但推荐用 new Error() 或其子类,这样有堆栈信息。
(4) 自定义错误消息
用 Error 的子类或自定义属性,提供更丰富的错误信息:
HTML
<script>
class ValidationError extends Error {
constructor(field, message) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
try {
throw new ValidationError("email", "邮箱格式不正确");
} catch (e) {
console.log(e.name + " [" + e.field + "]: " + e.message);
}
</script>
(5) 浏览器开发者工具(F12)
| 面板 | 用途 |
|---|---|
| Console | 查看日志、执行代码、查看错误 |
| Sources | 设置断点、逐步执行、查看变量值 |
| Network | 查看网络请求、响应状态、加载时间 |
| Elements | 查看/修改 DOM 和样式 |
断点调试是最强大的调试手段:在 Sources 面板点击行号设置断点,刷新页面后代码暂停在断点处,逐行执行、查看变量、调用栈一目了然。
(6) console 家族
| 方法 | 用途 |
|---|---|
console.log() |
普通输出 |
console.warn() |
警告(黄色) |
console.error() |
错误(红色) |
console.table() |
以表格展示数组/对象 |
console.time() / console.timeEnd() |
计时 |
console.group() / console.groupEnd() |
分组输出 |
console.clear() |
清空控制台 |
console.table 特别适合展示对象数组,比 log 直观太多。
(7) 调试技巧
- 逐条注释:注释掉一半代码,看哪半有问题,逐步缩小范围
- console.log 大法:在关键位置打印变量值,原始但有效
- 断点调试:比
console.log更强大,能暂停执行、实时修改变量 - 橡皮鸭调试法:对着橡皮鸭(或同事)逐行解释代码,经常解释到一半自己就发现 bug 了
▶ 示例:try/catch 处理 JSON 解析
▶ 试一试▶ 示例:自定义错误与表单验证
▶ 试一试▶ 示例:错误类型速查与 console 方法
▶ 试一试❓ 常见问题
Q try...catch 能捕获 SyntaxError 吗?
A 不能。
SyntaxError 在代码解析阶段就会抛出,根本执行不到 try。但如果 SyntaxError 是在运行时动态生成的(比如 JSON.parse 解析失败、new Function("bad syntax")),就可以被 catch。Q finally 什么时候用?
A 当你需要无论是否出错都执行清理操作时:关闭文件、释放资源、隐藏 loading 状态。大多数简单场景不需要 finally,catch 够用。
Q throw 和 return 有什么区别?
📖 小节
try/catch捕获运行时错误,finally无论是否出错都会执行,适合清理资源throw主动抛出错误,可以抛字符串、数字、Error 对象,推荐抛new Error("消息")Error对象有name和message属性,浏览器控制台会显示完整错误堆栈- 浏览器开发者工具(F12):Sources 面板设断点、Watch 变量、单步执行
console家族:log/warn/error/table/group/time/timeEnd,调试效率倍增器
📝 作业
- 写一个函数
safeDivide(a, b),用 try...catch 处理除零错误(提示:JS 中除以零不报错,需要自己判断并 throw),返回结果或错误信息。 - 写一个
safeJSONParse(str)函数,解析 JSON 字符串,如果失败返回{ success: false, error: 错误消息 },成功返回{ success: true, data: 解析结果 }。 - 写一个
retry(fn, times)函数:执行fn,如果抛错就重试,最多重试times次。如果全部失败,抛出最后一次的错误。用 try...catch 实现。