应尽量避免直接定义全局变量,必须使用时需通过IIFE封装私有作用域、统一挂载到单一命名空间、优先采用ES模块机制,并谨慎使用globalThis加唯一前缀或Symbol键。

全局变量在 JavaScript 中应尽量避免直接定义,但若必须使用,关键在于限制作用域、封装命名空间、利用模块机制来规避冲突与污染。
用立即执行函数(IIFE)封装私有作用域
将变量和逻辑包裹在函数作用域内,外部无法直接访问内部变量,只暴露必要的接口:
- 写法示例:const MyApp = (function() { let count = 0; return { increment() { count++; }, getCount() { return count; } }; })();
- 好处:count 是私有变量,不会与全局其他 count 冲突
- 注意:返回的对象方法仍可访问闭包内变量,但变量本身不挂载到 window 上
统一挂载到单一命名空间对象
不零散声明多个全局变量,而是集中挂在一个有意义的顶层对象下:
- 推荐写法:window.MyProject = window.MyProject || {};,再赋值 MyProject.utils = {...}、MyProject.config = {...}
- 避免写法:var apiToken = '...'; var version = '1.0';(直接污染全局)
- 兼容旧环境时,可用 typeof window !== 'undefined' ? window : globalThis 判断宿主对象
优先使用 ES 模块(ESM)替代全局声明
现代开发中,通过 export / import 管理依赖,天然隔离作用域:
立即学习“Java免费学习笔记(深入)”;
- 每个模块默认是独立作用域,const、let、function 不会自动成为全局变量
- HTML 中引入:<script type="module" src="main.js"></script>
- 如需跨模块共享,导出明确的 API,而非依赖全局变量
谨慎使用 globalThis + 唯一前缀或 Symbol 键
若确实需要扩展全局环境(如 polyfill 或框架入口),用 globalThis 并加业务标识:
- 安全写法:globalThis['MyApp_v2_utils'] = { debounce: ... };
- 更进一步:用 Symbol.for('MyApp.utils') 作为键名,降低字符串碰撞概率
- 切忌直接写 globalThis.myUtil = ... —— 名称太短极易被覆盖


















