JavaScript高级程序设计笔记 21
第21章 错误处理与调试
1. 错误处理
1.1 try-catch-finally
try:包裹可能出错的代码。catch(err):捕获错误,err是错误对象(包含name、message、stack等)。finally:无论是否出错都会执行,常用于清理(关闭连接、清除定时器等)。- 如果
catch中没有重新抛出错误,则程序不会中断。 finally中的 return 会覆盖try或catch中的 return。
try {
// 可能出错的代码
} catch (error) {
console.error(error.message);
} finally {
// 清理操作
}
1.2 throw 与错误类型
throw可以抛出任意值(字符串、数字、对象、Error 实例等)。- 内置错误类型:
Error:基类型。SyntaxError:语法错误。ReferenceError:引用未声明变量。TypeError:类型不匹配(如调用非函数)。RangeError:数值超出范围(如递归耗尽栈)。URIError:encodeURI/decodeURI参数无效。EvalError:eval()相关(很少见)。
- 自定义错误:继承
Error类。
class CustomError extends Error {
constructor(message) {
super(message);
this.name = 'CustomError';
}
}
throw new CustomError('自定义错误');
1.3 错误事件(全局捕获)
window.onerror:捕获未处理的 JavaScript 运行时错误(部分语法错误无法捕获)。- 参数:
message,source,lineno,colno,error。 - 返回
true可阻止默认处理(控制台报错)。
- 参数:
window.addEventListener('unhandledrejection'):捕获未处理的 Promise 拒绝。event.promise,event.reason。
window.onerror = (msg, url, line, col, err) => {
console.log('全局错误:', msg, err);
return true;
};
window.addEventListener('unhandledrejection', (event) => {
console.error('未处理的 Promise 拒绝:', event.reason);
});
2. 调试技术
2.1 console 方法
| 方法 | 说明 |
|---|---|
console.log(msg) |
普通输出 |
console.error(msg) |
错误样式,显示堆栈 |
console.warn(msg) |
警告样式 |
console.info(msg) |
信息样式 |
console.debug(msg) |
调试输出(可在控制台过滤) |
console.table(data) |
以表格形式输出数组/对象 |
console.time(label) / console.timeEnd(label) |
计时 |
console.group(label) / groupEnd() |
分组输出 |
console.trace() |
打印调用堆栈 |
console.assert(condition, msg) |
条件为假时输出错误 |
console.count(label) |
计数 |
console.dir(obj) |
显示对象的所有属性(DOM 元素显示为对象) |
2.2 debugger 语句
- 在代码中插入
debugger;,浏览器执行到该行时会自动暂停(需打开开发者工具)。 - 可配合断点、单步调试。
2.3 浏览器开发者工具
- 断点:行号点击设置,可设置条件断点(右键编辑)。
- 监视:在 Sources 面板添加表达式,实时查看值变化。
- 调用堆栈:查看函数调用顺序。
- 作用域:查看当前闭包、局部、全局变量。
- 异常断点:勾选 "Pause on exceptions",在抛出异常时自动暂停。
- XHR/fetch 断点:拦截特定 URL 请求。
- DOM 断点:元素变化(子树修改、属性修改、移除)时暂停。
2.4 性能与内存调试
- Performance 面板:记录执行过程,分析函数耗时。
- Memory 面板:堆快照,查找内存泄漏(闭包、未清理的 DOM 引用)。
- Coverage 面板:查看代码覆盖率。
3. 错误处理最佳实践
- 尽量 抛出错误对象(
throw new Error()),而非字符串或数字,以获取堆栈信息。 - 在 catch 中只处理可恢复的错误,无法恢复的应重新抛出或记录并上报。
- 异步代码(Promise/async) 必须处理拒绝(
.catch或try-catch),否则触发unhandledrejection。 - 使用
finally释放资源(如关闭文件、清除 loading 状态)。 - 生产环境 不应将错误详情直接暴露给用户,应记录到后端(通过
navigator.sendBeacon或 fetch)。 - 开发环境 可利用
console输出详细信息,结合断点调试。
4. 小结
- try-catch 拦错误,finally 收尾保无漏。
- throw 抛出自定义,Error 对象带堆栈。
- 全局捕获 onerror + unhandledrejection。
- 调试 console 方法多,debugger 断点不放过。
- 浏览器工具断点调,性能内存可检查。
5. 常见面试题速查
-
try-catch-finally 的执行顺序?
→ try 执行 → 若无错误跳过 catch → finally 始终执行。若 catch 中有 return,finally 会在 return 之前执行。 -
如何捕获异步代码中的错误?
→ Promise 使用.catch();async/await 使用try-catch;全局可监听unhandledrejection事件。 -
window.onerror能捕获所有错误吗?
→ 不能捕获try-catch中已处理的错误;也不能捕获资源加载错误(如图片、脚本),需用addEventListener('error')捕获资源错误。 -
throw可以抛出哪些类型的值?
→ 任意值,但推荐抛出Error实例或其子类,以便获得堆栈信息。 -
debugger语句的作用?
→ 代码执行到该行时会自动暂停(需打开开发者工具),方便调试。 -
如何打印调用堆栈?
→console.trace()或new Error().stack。 -
console.time和console.timeEnd的用途?
→ 测量代码段执行时间,自动输出到控制台。 -
finally中的 return 会影响 try 中的 return 吗?
→ 会,finally中的 return 会覆盖try或catch中的返回值。 -
如何捕获未处理的 Promise 拒绝?
→ 监听unhandledrejection事件。 -
生产环境下应该如何处理错误?
→ 记录错误到服务端,向用户显示友好提示(如“操作失败,请稍后重试”)。

浙公网安备 33010602011771号