模块执行上下文通过顶层函数作用域封装性实现静态私有,配合闭包、#私有字段或weakmap可达成真正不可访问的私有变量;其中#字段为语法级强制私有,weakmap用于兼容旧环境的实例私有数据模拟。

模块执行上下文本身不提供语法级私有机制,但通过其天然的**顶层函数作用域封装性**,配合闭包、私有字段或 WeakMap 等手段,可实现真正不可外部访问的私有变量。
ES6 模块顶层作用域即隐式闭包
每个 .js 模块在加载时,都会被 JavaScript 引擎自动包裹在一个隔离的函数作用域中(类似 IIFE)。该作用域内的 const、let、function 声明默认不会暴露到全局,也不被其他模块感知:
- 未导出的变量(如
const token = 'abc')在导入模块中直接引用会报ReferenceError - 这不是运行时“拦截”,而是静态作用域限制——变量根本不在导入方的作用域链中
- 这种隔离是模块系统的基础保障,但仅适用于模块内部顶层声明,不适用于对象属性或类实例状态
闭包封装:工厂函数与模块模式
当需要对外暴露对象或类,同时隐藏其内部状态时,必须主动构造封闭环境:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
-
工厂函数:每次调用生成独立闭包,适合多实例场景
function createLogger(prefix) { const id = Math.random(); return { log: msg => console.log(`[${id}] ${prefix}: ${msg}`) }; } -
IIFE 模块模式:适用于单例逻辑封装
const Config = (function() { const apiKey = 'secret_123'; return { getHost: () => 'api.example.com' }; })(); - 闭包内变量无法通过反射、
Object.keys或遍历原型链获取,具备运行时真正私有性
类私有字段(#name):语法级强制私有
ES2022+ 支持的 # 前缀字段,是目前最简洁、最严格的私有方案:
- 只能在类定义内部访问,实例外部读写均抛
TypeError - 支持方法、getter/setter、静态私有字段,且不参与枚举、
JSON.stringify或for...in - 示例:
class Cache { #data = new Map(); set(k, v) { this.#data.set(k, v); } } - 注意:私有字段名不可动态计算(
this[#key]不合法),需静态确定
WeakMap 模拟实例私有数据(兼容旧环境)
在不支持 # 字段的环境中,可用 WeakMap 将私有状态与实例绑定:
- 以实例为键,存储专属数据,避免属性名暴露,也防止内存泄漏
- 需手动维护映射关系,通常配合构造函数或类初始化使用
- 示例:
const _cache = new WeakMap(); class Store { constructor() { _cache.set(this, { items: [] }); } add(x) { _cache.get(this).items.push(x); } } - 比
_命名约定更可靠,但不如#字段直观和安全










