避免全局变量污染的关键在于有意识控制变量可见范围和挂载方式:优先使用ES模块、let/const声明与严格模式,辅以IIFE封装或统一命名空间挂载。

避免全局作用域变量污染,核心不是“躲开全局”,而是有意识地控制变量的可见范围和挂载方式——函数作用域、块级作用域、模块机制和命名空间都是工具,关键在怎么用。
用 let/const 声明 + 严格模式兜底
var 声明会变量提升且作用域宽松,容易意外泄漏;let 和 const 是块级作用域,声明即绑定,不会自动挂到 window 或 globalThis 上。
- 写 let count = 0 或 const API_URL = '...',而不是 count = 0(隐式全局)或 var count = 0(易被提升干扰)
- 在脚本顶部加 "use strict":一旦出现 name = 'x' 这类未声明赋值,直接报错,不给污染机会
- 检查 this 绑定——普通函数里 this.name = 'x' 在非严格模式下等于 window.name = 'x',要警惕
用 IIFE 封装一次性逻辑
没有模块系统时,IIFE 是最轻量的隔离手段,所有内部变量天然私有,只暴露真正需要的接口。
- 写成 (() => { const token = 'abc'; window.MyApp = { login() { /* 用 token */ } }; })();
- 不把整个对象扔进全局,而是显式挂到一个顶层命名空间上,比如 window.MyApp
- 如果需兼容 Node.js,传参方式更稳妥:(global => { global.MyApp = { ... }; })(typeof window !== 'undefined' ? window : globalThis);
优先走 ES 模块(ESM)路径
现代开发中,<script type="module"> 让每个文件默认拥有独立作用域,顶层声明不会自动成为全局变量,这是最自然、最可持续的防污染方式。
立即学习“Java免费学习笔记(深入)”;
- 不用 IIFE 包裹,也不用 window.xxx =,直接写 const helper = () => {},它就只在当前模块内有效
- 需要共享?用 export 显式导出,用 import 显式引入,依赖清晰可追溯
- 即使没构建工具,浏览器原生支持 ESM,无需额外配置即可启用
统一挂载到单一命名空间对象
若必须暴露全局标识符,只暴露一个,其余全作为它的属性存在,大幅压缩污染面。
- 写 window.AcmeSDK = window.AcmeSDK || {};,再往里面加 AcmeSDK.utils、AcmeSDK.api
- 支持嵌套创建:AcmeSDK.data = AcmeSDK.data || {};,避免重复定义或覆盖
- 搭配 IIFE 初始化,既保护私有状态(如缓存、计数器),又对外提供干净接口


















