try...catch仅捕获同步运行时错误,对语法错误、异步错误及未await的Promise拒绝无效;async/await中配合await可捕获Promise拒绝;catch必须带参数;finally总执行,适用于资源清理。

JavaScript 的 try...catch 能捕获运行时错误,但对语法错误、异步错误(如 setTimeout 中抛出的)、Promise 拒绝(reject)默认无效 —— 这是多数人踩坑的起点。
什么时候 try...catch 有效?
它只捕获当前执行栈中同步抛出的错误(throw)或内置异常(如 ReferenceError、TypeError)。
- ✅ 有效场景:函数内直接调用出错、JSON.parse 解析失败、访问
undefined的属性等 - ❌ 无效场景:
setTimeout(() => { throw new Error() })、fetch().catch()、顶层语法错误(如let x = ;) - ⚠️ 注意:
async/await函数里用try...catch是有效的,因为await将 Promise 拒绝转为同步抛出(前提是没被上层 Promise 吞掉)
catch 块必须带参数吗?
是的。ES2019+ 要求 catch 必须声明错误绑定变量(哪怕不用),写成 catch (err) 或 catch (_) 都可以,但 catch {} 会报语法错误。
try {
JSON.parse('{ "x": }'); // SyntaxError
} catch (err) { // ✅ 必须有参数
console.log(err.message); // "Unexpected token }"
}
要不要加 finally?什么情况下必须用?
finally 在 try 或 catch 执行完后**总会运行**,适合清理资源,比如关闭加载状态、释放锁、重置计时器。
立即学习“Java免费学习笔记(深入)”;
- ✅ 推荐用在 UI 加载场景:
loading = true放try前,loading = false放finally里,确保无论成功失败都收尾 - ❌ 不要用
finally替代catch—— 它不接收错误,也无法阻止错误向上冒泡 - ⚠️ 如果
finally里也throw或返回 Promise 拒绝,会覆盖前面的错误或返回值
Promise 错误不能靠 try...catch?那怎么统一处理?
原生 Promise 构造函数内部抛错不会进外层 try...catch;必须显式用 .catch() 或 await + try...catch。
try {
Promise.reject(new Error('nope')); // ❌ 不会被捕获
} catch (e) {
// 永远进不来
}
// ✅ 正确方式 1:链式 .catch()
Promise.reject(new Error('yep')).catch(e => console.error(e));
// ✅ 正确方式 2:await + try
async function f() {
try {
await Promise.reject(new Error('yep'));
} catch (e) {
console.error(e); // 进得来
}
}
全局未捕获 Promise 拒绝可用 window.addEventListener('unhandledrejection') 监听,但只是兜底,不能替代业务层处理。











