全局变量本质是全局对象属性,存在命名冲突、静默污染、内存泄漏及模块化不一致四类风险。

全局变量在 JavaScript 中本质上就是全局对象(浏览器里是 window,Node.js 里是 global)的属性。这种“挂载关系”看似方便,实则埋下了几类典型风险。
命名冲突直接表现为属性覆盖
当你写 let username = "Alice" 在全局作用域,等价于 window.username = "Alice"。如果另一段脚本(比如第三方库或同事代码)也声明了同名全局变量,后执行的会覆盖先定义的值。
- 常见场景:两个插件都定义
utils或config,最终只有一个生效 - 调试表现:某处突然取不到预期值,但控制台打印
window.utils却有内容——说明被意外改写了
未声明赋值会静默污染全局对象
忘记用 let/const/var 直接写 message = "hello",JS 引擎会自动把它加到 window.message 上。这在非严格模式下不会报错,但极易引入隐蔽 bug。
- 风险点:函数内部漏写
let,本该是局部变量却成了全局属性 - 检测方式:开启
"use strict"后,这类操作会立即抛出ReferenceError
生命周期长导致内存难以释放
全局变量只要页面没刷新、进程没退出,就不会被垃圾回收。尤其当它引用了 DOM 节点、大型数组或闭包时,可能长期占用内存。
立即学习“Java免费学习笔记(深入)”;
- 典型问题:监听器绑定到全局变量上,又没手动移除,造成内存泄漏
- 识别方法:Chrome DevTools 的 Memory 面板中查看
window对象下的引用链
模块化环境下行为不一致
ES6 模块(import/export)默认运行在严格模式且不共享全局作用域。你在模块顶层写的 let x = 1 并不会变成 window.x,但 window.x = 1 依然有效——这种混用容易让人误判变量可见性。
- 陷阱示例:在模块中通过
window.apiToken存 token,结果其他模块无法直接读取apiToken变量名 - 解决方向:统一用
export提供接口,而非依赖window属性


















