try...catch...finally
try...catch...finally
是 JavaScript 中用于 异常处理 的语句结构,它能帮助我们在运行时捕捉并处理错误,确保即使出错也能有优雅的降级逻辑,并在 finally
中执行清理操作。
✅ 一、基本用法
js
try {
// 可能会抛出错误的代码
let result = riskyOperation();
console.log(result);
} catch (error) {
// 捕获错误后的处理
console.error('出错了:', error.message);
} finally {
// 无论是否出错都会执行的代码(如关闭连接、释放资源等)
console.log('操作完成');
}
执行顺序:
try
中代码正常执行- 如果报错,跳过 try 中剩下的代码,进入
catch
- 最后一定会进入
finally
(无论 try/catch 报不报错)
💡 二、特殊用法
1. catch 是可选的(ES10+)
js
try {
doSomething();
} finally {
console.log("无论是否出错我都会执行");
}
✅ 适用于:只需要清理资源,不关心错误本身
2. 异常信息可选
js
try {
doSomething();
} catch {
console.log("捕获到了错误,但不关心具体信息");
}
✅ 适用于:不关心具体错误信息
3. finally 中的 return/throw 会覆盖 try 或 catch 的返回值
js
function test() {
try {
return 'try';
} catch (e) {
return 'catch';
} finally {
return 'finally';
}
}
console.log(test()); // 👉 输出 "finally"
⚠️ finally 中的
return
会 覆盖 任何前面return
的值!
4. catch 参数是作用域独立的
js
let error = '外部错误';
try {
throw new Error('内部错误');
} catch (error) {
console.log(error.message); // 👉 "内部错误"
}
console.log(error); // 👉 "外部错误"
✅
catch(error)
中的error
是一个 块级作用域变量,不会污染外部。
⚠️ 三、常见易错点
❌ 忘记 finally 覆盖了 return/throw
js
function example() {
try {
throw new Error("boom");
} catch (e) {
return "catch";
} finally {
return "finally"; // 会覆盖 catch 的返回值!
}
}
console.log(example()); // 输出 "finally"
finally 中的 return、 throw、 break、 continue 都会覆盖前面 try / catch 的返回值。
❌ try 内异步代码无法被 catch 捕获
js
try {
setTimeout(() => {
throw new Error("异步错误");
}, 1000);
} catch (e) {
// 无法捕获异步错误
console.log("catch 到了:", e.message);
}
✅ 正确做法:使用 Promise 的
.catch()
或 try...catch 搭配 async/await
js
(async () => {
try {
await Promise.reject(new Error("异步错误"));
} catch (e) {
console.log("捕获到了:", e.message);
}
})();
📌 四、使用建议
场景 | 是否使用 try...catch |
---|---|
用户输入/外部接口 | ✅ 推荐加 try...catch 捕获异常 |
DOM 操作/文件读写 | ✅ 推荐使用,增强稳定性 |
纯同步、性能敏感代码 | ⚠️ 不要滥用,try...catch 有性能开销 |
异步代码(Promise) | ❌ 不能直接捕获,用 .catch() 或 async/await |
✅ 五、总结口诀
try
放逻辑,catch
抓错误,finally
善后不打折;finally
的 return 是个坑,会覆盖前面返回值;- 异步错误不归 catch 管,得靠 Promise 来补帆。