模块化开发通过ES6模块作用域隔离全局变量,顶层声明默认不污染globalThis;需显式export/import共享内容;对非模块脚本用IIFE、命名空间或打包器沙箱控制。

模块化开发中,全局作用域变量的隔离不是靠“删除”或“禁止”,而是通过明确的作用域边界和可控的暴露机制,让变量待在该待的地方,不自动挤占 window 或 globalThis。
用 ES6 模块天然隔离顶层声明
每个 .js 文件作为 ES6 模块时,默认拥有独立模块作用域。文件顶部用 let、const 或 function 声明的内容,不会自动成为全局变量。
- 即使写
const apiHost = 'https://api.example.com';,它也只在当前模块内有效 - 外部必须通过
export显式导出,再由其他模块import引入才能使用 - 没有
export的变量,连同整个模块作用域,对其他模块完全不可见
避免意外挂载到 window 上
有些老代码或第三方库会主动执行 window.xxx = ... 或 this.xxx = ...,尤其在非模块环境中运行时。需主动拦截或重写。
- 加载脚本前,可临时覆盖
window的属性赋值行为(调试或兼容场景) - 使用 Webpack 的
externals配置,把 jQuery 等库从打包结果中排除,改用 CDN +import $ from 'jquery'的 ESM 形式,避免其默认挂载$和jQuery - 若必须加载未模块化的脚本,用 IIFE 包裹并启用严格模式:
(function() { "use strict"; /* 脚本内容 */ })();
统一命名空间仅用于显式桥接
当确实需要跨模块共享少量配置或工具函数时,不放任各自声明全局变量,而是集中挂载到一个受控对象下。
立即学习“Java免费学习笔记(深入)”;
- 只创建一个顶层命名空间,比如
window.APP_CONFIG或window.MyLib - 用安全初始化方式:
const MyLib = window.MyLib = window.MyLib || {}; - 所有模块向这个对象添加子属性,如
MyLib.api = {...}、MyLib.utils = {...},避免多个脚本都直接写utils = {...}导致覆盖
构建工具强化沙箱环境
Webpack、Vite 等现代打包器会在编译阶段自动将每个模块包裹进函数闭包,即使代码里用了 var,实际运行时也不会泄漏到全局。
- 配合 TypeScript 编译,能提前识别重复导出、未使用导出,减少人为命名疏漏
- ESLint 规则如
no-var、no-implicit-globals可强制开发者避免隐式全局声明 - 开启
"type": "module"的 package.json,确保 Node.js 环境也按模块方式解析文件


















