news 2026/7/19 5:56:02

JavaScript 异常捕获完全指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript 异常捕获完全指南

文章目录

  • 一、基础结构:try...catch...finally
  • 二、错误对象 Error
    • 1. 内置错误类型
    • 2. 自定义错误
  • 三、主动抛出:throw
  • 四、不同错误类型的精准捕获
  • 五、finally 的妙用
  • 六、异步异常捕获
    • 1. Promise 的 catch
    • 2. async/await + try/catch
    • 3. 事件循环中的错误
  • 七、全局异常捕获(兜底防线)
    • 1. window.onerror
    • 2. window.addEventListener('error')
    • 3. unhandledrejection 事件

在开发中,错误不可避免——网络请求失败、用户输入非法、第三方脚本出错……如果放任不管,一个未捕获的异常就可能让整个应用白屏崩溃。异常捕获正是赋予我们“预判风险、优雅降级”的能力。JS 提供了丰富的错误处理手段,下面逐一解析。

一、基础结构:try…catch…finally

这是处理同步代码异常的核心语法。

try{// 尝试执行的代码letdata=JSON.parse(jsonStr);}catch(error){// 当 try 块中抛出错误时执行 console.error('解析失败:', error.message);}finally{// 无论是否出错,最终都会执行 console.log('清理临时变量、关闭连接等');}

执行流程
1、执行 try 中的代码。
2、如果没有异常,跳过 catch,执行 finally。
3、如果抛出异常,try 中后续代码立即停止,进入 catch;执行完catch 后再进入 finally。
4、finally 即使在 try 或 catch 中有 return,也依然会执行(在真正返回前执行)。
注意:catch 捕获的必须是 try 块中同步执行时抛出的错误。若是异步回调中的错误(如 setTimeout),外层 try/catch 无能为力,后文会详解。

二、错误对象 Error

1. 内置错误类型

JS 内置了多种错误构造函数,可通过 instanceof 区分:

1、Error —— 通用错误
2、SyntaxError —— 语法错误
3、ReferenceError —— 引用错误(变量不存在)
4、TypeError —— 类型错误
5、RangeError —— 数值超出范围
6、URIError —— URI 处理函数错误
每种错误都包含 name、message、stack 等属性。stack 记录了调用栈,是调试的利器。

2. 自定义错误

扩展 Error 类可以创建业务专用错误,携带更多上下文信息。

class ApiError extends Error{constructor(message, statusCode){super(message);this.name='ApiError';this.statusCode=statusCode;}}try{throw new ApiError('Not Found',404);}catch(err){if(err instanceof ApiError){console.error(`API 错误 ${err.statusCode}: ${err.message}`);}}

三、主动抛出:throw

任何值都可以被 throw(但推荐抛出 Error 对象),它能够中断当前执行流,并沿着调用栈向上传播,直到被 catch 捕获。

functiondivide(a, b){if(b===0){throw new Error('除数不能为零');}returna / b;}

四、不同错误类型的精准捕获

catch 块可以结合 instanceof 或 error.name 来做分类处理。

try{// 可能抛出多种错误的代码}catch(err){if(err instanceof TypeError){// 处理类型错误}elseif(err instanceof RangeError){// 处理范围错误}else{// 其他未知错误重新抛出 throw err;}}

重新抛出是一个重要技巧:只处理你预期的错误,未预料的错误继续向上抛给上层逻辑。

五、finally 的妙用

finally 适合放“必须执行”的清理代码,比如关闭文件流、清除定时器、隐藏 loading 效果等。即使 try 或 catch 中执行了 return,finally 也会在返回值真正交付之前运行。

functiongetUser(){showLoading();try{returnfetchData();// 即使这里 return,finally 仍会执行}catch(e){returndefaultData;}finally{hideLoading();// 必然执行,保证 loading 隐藏}}

注意:如果 finally 中显式 return,它会覆盖 try/catch 中的返回值,需谨慎。

六、异步异常捕获

这是前端异常处理中最容易出问题的环节。

1. Promise 的 catch

Promise 内的错误(包括 reject 和运行时错误)都会被 catch 捕获,不会冒泡到外层同步 try/catch。

fetch('/api/user').then(res=>res.json()).then(data=>{// 如果这里抛出错误,会被后面的 catch 捕获 console.log(data.info);}).catch(err=>{console.error('请求失败:', err);});

2. async/await + try/catch

async 函数使异步代码看起来像同步,因此 try/catch 可以直接捕获 await 表达式的异常。

asyncfunctionloadUser(){try{const response=await fetch('/api/user');const data=await response.json();returndata;}catch(err){console.error('加载用户失败', err);// 返回降级数据或重新抛出return{name:'匿名用户'};}}

重要:await 会将 Promise 的 reject 转化为同步异常,所以 try/catch 有效。但别忘了 async 函数自身返回的是 Promise,调用方也需要处理可能的异常。

3. 事件循环中的错误

setTimeout、setInterval 等回调在下一个事件循环中执行,外层的 try/catch 完全无效。

try{setTimeout(()=>{throw new Error('定时器错误');// 全局异常,外层 try 捕获不到},1000);}catch(e){// 不会执行}

正确的做法是在回调内部自行 try/catch,或依赖全局异常捕获机制。

七、全局异常捕获(兜底防线)

即使项目代码再完善,仍可能有遗漏的未捕获异常。浏览器提供了全局监听手段,用于错误上报与友好提示。

1. window.onerror

捕获全局同步运行时错误(除 Promise 外)。

window.onerror=function(message, source, lineno, colno, error){console.error('全局错误捕获:', message,'at', source, lineno);// 上报到监控平台returntrue;// 返回true可阻止浏览器默认报错行为};

2. window.addEventListener(‘error’)

更强大的监听,可以捕获资源加载失败(如 404、脚本加载失败)以及运行时错误(比 onerror 稍晚触发,但信息更全)。

window.addEventListener('error',(event)=>{if(event.target instanceof HTMLImageElement){console.error('图片加载失败:', event.target.src);}else{console.error('运行时错误:', event.message);}},true);// 使用捕获阶段,因为资源错误不冒泡

3. unhandledrejection 事件

专用于捕获未被 .catch() 或 try/catch 处理的 Promise 拒绝。

window.addEventListener('unhandledrejection', event=>{console.error('未处理的 Promise 拒绝:', event.reason);// 可以调用 event.preventDefault()防止控制台默认报错});

现代前端监控体系通常会结合这三种全局事件 + 框架级错误边界(如 React Error Boundary)来实现完善的异常收集。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/19 5:54:10

Ubuntu 22.04编译AOSP Android 13完整指南

1. 环境准备与系统配置在Ubuntu 22.04上编译AOSP Android 13需要先完成基础环境搭建。我推荐使用物理机而非虚拟机进行编译,因为Android源码编译对硬件资源要求较高。以下是经过实测的配置方案:1.1 硬件需求建议CPU:至少8核(推荐1…

作者头像 李华
网站建设 2026/7/19 5:49:15

Winform多线程UI操作简化与优化实践

1. Winform多线程操作委托简化的核心痛点在Winform开发中,多线程操作UI控件是个老生常谈却又让开发者头疼的问题。微软在设计Winform时采用了单线程模型,这意味着所有UI操作都必须在创建控件的线程(通常是主线程)上执行。当我们需…

作者头像 李华
网站建设 2026/7/19 5:46:24

Unity与VS2013/2015调试集成:原理、配置与实战排错指南

1. 项目概述:为什么Unity开发者需要关注VS版本与调试工具作为一名在Unity和Visual Studio(VS)生态里摸爬滚打了多年的老程序员,我见过太多因为开发环境配置不当而导致的“玄学”问题。一个最常见,也最容易被忽视的环节…

作者头像 李华
网站建设 2026/7/19 5:46:07

CANoe CAPL中Checksum与Counter的实现与应用

1. CANoe CAPL中的Checksum与Counter基础解析在汽车电子测试领域,数据完整性和消息顺序验证是确保通信可靠性的两大基石。CANoe作为主流的车载网络测试工具,其CAPL(CAN Access Programming Language)脚本语言提供了灵活的实现手段…

作者头像 李华