JavaScript 中 try...catch 异常处理详解与最佳实践
本文详细解析 JavaScript 中 try...catch 语句的语法结构、执行流程及多种应用场景。涵盖无错与报错情况下的代码行为、语法错误的局限性、多层嵌套逻辑,以及针对 setTimeout 宏任务和 Promise 微任务等异步操作的错误捕获难点。同时介绍 async/await 的同步化优势及 window.onerror 全局错误监控方案,帮助开发者构建健壮的代码容错机制。
一、语法
try 语句由一个或多个语句组成的 try 块构成,并必须包含至少一个 catch 块或 finally 块,或者两者兼有。以下是三种常见的 try 声明形式:
try...catch
try...finally
try...catch...finally
try {
// 需要被执行的语句
} catch (err) {
// 如果在try块里有异常被抛出时执行的语句
} finally {
// 在try语句块之后执行的语句块。无论是否有异常抛出或捕获这些语句都将执行。
}
在代码中,
try块内的语句会优先执行。若运行期间发生错误,控制流将跳转至catch块中的语句,括号内的err参数作为异常变量传入。若未发生错误,catch块内的语句将被跳过。无论是否发生错误,或是catch块执行完毕,亦或是try块正常结束,最终都会执行finally块中的语句。
二、举例
2.1. 无错误情况
try {
alert('开始执行 try1'); // (1)
alert('开始执行 try2'); // (2)
} catch (err) {
alert('catch 被忽略,因为没有 error,不会被执行'); // (3)
}
上述代码将依次弹出“开始执行
try1”和“开始执行try2”,但不会弹出“catch被忽略,因为没有error”的提示。
2. 2. 有错误情况
try {
alert('开始执行 try1'); // (1)
throw "此处抛出错误"; //try块里到此结束,不会在执行下边的try2
alert('try2,不会被执行'); // (2)
} catch (err) {
alert('出现了 error,此句被执行'); // (3)
}
上述代码将弹出“开始执行
try1”以及“出现了error,此句被执行”的提示。
2.3. try…catch 仅对可执行代码有效
要使
try...catch生效,代码必须是可执行的,即符合有效的JavaScript语法规范。若代码包含语法错误,try..catch将无法正常工作,例如以下代码中存在多余的逗号:
try {
,,,,,,//js引擎无法理解这段代码,它是无效的
throw "此处不会抛出错误"; //不会执行
alert('try2,此句不会被执行'); // (2)
} catch (err) {
alert('此句不会被执行'); // (3)
}
2.4. try catch 嵌套
try {
try {
throw new Error("try1");
}
finally {
console.log("finally");
}
}
catch (err) {
console.error("outer", err.message);
}
会输出
// finally
// outer try1
try {
try {
throw new Error("try1");
}
catch (err) {
console.error("inner", err.message);
}
finally {
console.log("finally");
}
}
catch (err) {
console.error("outer", err.message);
}
会输出
// inner try1
// finally
try {
try {
throw new Error("try1");
}
catch (err) {
console.error("inner", err.message);
// return 如果我在此处写个return会是什么结果? (下边的报错信息肯定不会抛出了,当然return必须是在函数里)
throw new Error("try2"); //试想一下,如何把此句代码放在下边的finally里会怎么输出?(结果一样)
}
finally {
console.log("finally");
}
}
catch (err) {
console.error("outer", err.message);
}
会输出
// inner try1
// finally
// outer try2
try {
try {
throw new Error("try1");
}
catch (err) {
console.error("inner", err.message);
throw new Error("try2");
}
finally {
console.log("finally");
return //终止了错误的抛出
}
}
catch (err) {
console.error("outer", err.message); //不会被执行
}
会输出
// inner try1
// finally
2.5. try…catch 无法捕获异步任务异常
2.5.1. 异步任务->宏任务setTimeout
try {
setTimeout(()=>{
throw new Error('错误信息')
}, 1000);
} catch (err) {
alert( "alert不会执行" );
}
由于
try...catch包裹了延迟执行的函数,当该函数计划执行时,js引擎早已离开try...catch结构,导致上下文环境改变,因此无法捕获异步任务内部的错误。为了捕获计划函数中的异常,try...catch必须置于setTimeout函数内部,如下所示:
setTimeout(() => {
try {
throw new Error("错误信息");
} catch (err) {
alert("alert会执行");
}
}, 1000);
2.5.2. 异步任务->微任务promise
try...catch同样无法捕获微任务的异常,原理与2.5.1中的两段代码try,catch一致,它们均无法捕获错误信息。这是因为promise内部的错误不会向外冒泡,而是被promise内部机制处理,唯有通过promise.catch才能捕获promise的错误情况。
function test() {
Promise.resolve("1").then(() => {
throw new Error("错误信息");
});
}
try {
test();
} catch (err) {
alert("不工作");
}
try {
Promise.reject("错误信息");
} catch (e) {
console.log(e.message);
}
2.6. try…catch async/await 的异常捕获
async/await允许异步代码以同步方式执行,因此可以直接进行异常捕获。
// 例子1
async function test() {
throw new Error("错误信息");
return 0;
}
test()
.then()
.catch((e) => console.log(e.message)); // 错误信息(可以捕获到错误信息)
// 例子2
function promiseFn() {
return new Promise((resolve, reject) => {
throw new Error("错误信息");
});
}
async function test() {
try {
const res = await promiseFn();
} catch (e) {
console.log(e.message); //错误信息(可以捕获到错误信息)
}
}
test();
// 例子3
function promiseFn() {
return Promise.reject("错误信息");
}
async function test() {
try {
const res = await promiseFn();
} catch (e) {
console.log(e); //错误信息(可以捕获到错误信息)
}
}
test();
2.7. 全局监听抛出的错误
- 上述方法仅能通过
try catch、then捕获同步与异步错误。 - 这些属于局部错误捕获手段。当无法保证所有代码均处理了异常时,可实施全局异常监控。
通常有两种实现方式:
- window.addEventListener(‘error’)
- window.addEventListener(‘unhandledrejection’)
- error 事件可监听所有同步及异步的运行时错误,但无法监听语法错误、接口请求错误或资源加载错误。
- 而 unhandledrejection 事件可监听 Promise 中抛出且未被 .catch 捕获的错误。
window.addEventListener("error", function (e) {
var error = e.error;
console.log(error); //错误信息
});
document.querySelector("button").addEventListener("click", () => {
throw new Error("错误信息");
});总结
至此,关于 JS try catch 用法举例之异常处理的文章介绍完毕,更多相关 JS try catch 异常处理内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
JS语法错误会阻止加载吗?区分SyntaxError与资源加载失败
2026-11-05 16:08:46
JavaScript常见SyntaxError语法错误排查与修复方法
2026-11-05 13:58:44
JS中slice、substring和substr截取字符串的区别
2026-11-05 13:43:47
JS 转 TS 手动迁移最佳实践:从配置 tsconfig 到消除 any 类型
2026-11-05 11:53:32
为什么JS数组push后得到的是数字而不是数组?
2026-11-05 09:59:18
相关标签:
