模块模式用闭包将组件逻辑锁进独立作用域,仅暴露明确接口;iife实现单例私有沙箱,工厂函数支持多实例隔离,私有状态天然不可访问,兼容全js环境。

模块模式用闭包把组件逻辑“锁”进独立作用域,只留明确接口对外交互。它不靠语法糖实现私有,而是靠函数作用域天然隔离——变量没被 return 出去,外部就真的访问不到。
用 IIFE 封装单个可复用组件
IIFE 是最轻量、最兼容的私有沙箱,适合封装状态轻、全局唯一的 UI 组件或工具类:
- 把组件内部状态(如 loading、error、缓存数据)、DOM 引用、辅助方法全写在立即执行函数内
- 所有 let/const 声明自动私有,不会污染全局或被意外修改
- return 的对象只暴露必要方法,比如 render()、update()、destroy()
- 可在开头做一次性初始化:绑定事件委托、预加载模板、设置默认配置
用工厂函数创建多实例组件
当需要多个相互隔离的组件实例(比如多个表单验证器、不同区域的地图控件、多租户消息弹窗),必须避免共享状态:
- 把模块写成函数,接收配置参数(如 container、theme、apiBase)
- 每次调用生成全新闭包,每个实例拥有独立的 privateCache、retryCount、eventListeners
- 返回的对象方法仍能安全读写所属闭包内的数据,但无法跨实例访问
- 适合微前端子应用、插件化 SDK、AB 测试组件等场景
暴露接口时守住封装边界
公有方法是唯一入口,所有敏感操作和校验必须收在内部,防止绕过:
- 不返回原始数据引用,比如避免 return { data: privateStore };改用 getter 或 snapshot 方法
- 对入参做类型与范围校验,统一由私有函数处理(如 _validateConfig()、_normalizeProps())
- 异步中间状态(如 pending、fetched)藏在闭包里,只通过 isLoaded() 或 onStateChange() 通知
- 提供 destroy() 方法,在其中清理定时器、事件监听、DOM 引用,释放闭包持有的资源
适配不同环境靠驱动契约,不靠平台 API
模块本身不关心运行在哪,只约定“怎么驱动它”:
- 不直接调用 document.querySelector 或 fetch,而是定义 setDriver({ query, request, render })
- 宿主按需注入 DOM 操作器、HTTP 客户端、动画引擎等符合接口的实现
- 模块仅依赖标准 ES5+ 语法,IIFE 兼容浏览器、小程序、Node.js、uni-app 等所有 JS 环境
- 打包时加一层 export default 或 module.exports =,即可适配 ESM、CommonJS、UMD 各种引入方式











