JS内存泄漏源于长期强引用导致对象无法回收,需切断意外引用链:WebSocket须统一管理并显式close,定时器需clear,DOM引用和事件监听要同步清理,闭包避免捕获大对象。

JS 内存泄漏不是由单次错误引发的,而是某些“看似合理”的写法长期持有强引用,让本该回收的对象持续驻留。规避关键在于切断意外引用链,把资源生命周期收口到可控范围内。
别让 WebSocket 成为内存黑洞
组件反复挂载又卸载,却每次新建 WebSocket 实例、不关闭旧连接,是最典型的泄漏路径。
- Vue 中不要在 mounted 里直接
new WebSocket();React 中不要在 useEffect 里无清理地创建 - 避免用事件总线二次包装 ws 消息——清空了总线 listeners,但原始
ws.onmessage还挂在那儿 - 全局单例或 Context 存 ws 实例时,必须提供 destroy() 方法,并在组件卸载时调用;仅靠判断
readyState === 3不代表可丢弃,没调close()就仍强可达 - 推荐封装一个连接管理器:构造时建 ws + 启心跳,暴露
destroy()统一执行ws.close()和监听器解绑
定时器和回调别偷偷续命
setInterval 是泄漏加速器——只要没 clear,回调函数及其闭包就一直活着,连带它捕获的所有对象。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- 组件销毁、路由跳转前,务必调用
clearInterval(id)或clearTimeout(id) - 避免在回调中直接访问
this、大型 props/state 或 DOM 节点;若必须用,确保清除时机明确 - 现代方案可用 AbortController 配合
setTimeout实现可取消延时,减少手动 ID 管理
DOM 引用和事件监听要同步清理
DOM 元素被 remove() 或 innerHTML = '' 清掉,不代表 JS 里的引用自动失效。
- 缓存过
const el = document.getElementById('chart')?后续移除 el 后,记得把chartInstance等持有它的变量也置为null - 用
addEventListener绑定的监听器,必须用对应removeEventListener解绑;React 中可在 useEffect 清理函数 里统一处理 - 优先使用
{ once: true }选项,或委托到父级用事件冒泡处理,减少监听器数量
闭包别无意兜住大对象
闭包本身不危险,危险的是它长期存活 + 捕获了不该留下的数据。
- 返回函数被导出、存入全局 Map 或作为事件回调长期保留时,检查它是否捕获了体积庞大的数组、对象或 DOM 节点
- 不需要时主动断开引用:
bigData = null;或改用 WeakMap 存储关联数据,避免强引用拖住目标对象 - 避免闭包与 DOM 元素互相引用形成的循环,尤其在旧版 IE 兼容场景下更需警惕

















