全局变量引发内存泄漏,因其生命周期与页面共存且始终可达,垃圾回收器无法释放其所引用的数据;常见于未声明赋值、显式挂载window、函数内this指向window等场景。

全局变量会引发内存泄漏,根本原因是它的生命周期与页面共存——只要页面没关闭,它就一直“活着”,所引用的数据也无法被垃圾回收器释放。
为什么全局变量不被回收
JavaScript 的垃圾回收机制(GC)只清理“不可达对象”。而全局变量(比如挂在 window 上的属性)始终可通过全局对象访问,属于“永远可达”,所以 GC 永远跳过它。
- 未声明直接赋值:如
data = [1,2,3,...],自动变成window.data - 显式挂到 window:如
window.cache = new Array(1e6) - 函数内 this 指向 window:如
function f() { this.id = 'leak' },调用f()后window.id就存在了
典型泄漏场景
这些写法看着简单,但容易让大块数据长期驻留内存:
- 忘记声明变量:
function load() { rawData = fetchBigData(); }→rawData成为全局 - 调试时临时挂载:
window.debugInfo = { hugeLog: [] },上线后忘了删 - 模块间误共享:
var config = {...}写在顶层,被多个模块反复引用并修改,体积不断膨胀
怎么避免和修复
不是不能用全局变量,而是要控制它的“存在感”和“寿命”:
立即学习“Java免费学习笔记(深入)”;
- 开启严格模式:
'use strict',未声明赋值会直接报错,从源头拦截 - 始终用
let/const声明,哪怕在模块顶层,也属于模块作用域,非真正全局 - 真需跨模块共享?用单例或依赖注入,而不是往
window上塞 - 已存在的全局缓存,用完及时置空:
window.cachedData = null,断开引用链
顺便提醒一个隐藏风险
console.log 也可能间接导致泄漏——开发工具为了让你能展开查看,会保持对传入对象的强引用。如果日志里打印了大型 DOM 节点、闭包或数组,且控制台一直开着,这些对象就暂时无法回收。上线前记得删掉或注释掉调试用的 console。


















