WeakMap 是 JavaScript 中实现私有数据隔离的可靠方式,适合配合工厂函数封装内部状态;其键必须是对象且弱引用,能自动垃圾回收,确保实例间私有数据隔离、不可枚举、无法外部直接访问。

WeakMap 是 JavaScript 中实现私有数据隔离的可靠方式,特别适合配合工厂函数封装内部状态,避免属性被意外访问或修改。
用 WeakMap 存储实例私有数据
WeakMap 的键必须是对象,且对键是弱引用——当对象不再被其他地方引用时,对应的 WeakMap 条目会自动被垃圾回收。这使其天然适合作为“私有存储容器”,绑定到实例对象上而不影响其生命周期。
工厂函数每次返回一个新对象,WeakMap 则为每个实例单独维护一份私有数据,彼此隔离、不可枚举、无法从外部直接访问。
基础写法:闭包 + WeakMap 双重保护
把 WeakMap 实例定义在工厂函数作用域外(或模块顶层),确保所有实例共享同一个 WeakMap,但各自的数据互不干扰:
立即学习“Java免费学习笔记(深入)”;
const privateData = new WeakMap();
function createCounter(initial = 0) {
const instance = {};
// 为当前 instance 设置私有状态
privateData.set(instance, { count: initial });
instance.increment = function() {
const data = privateData.get(this);
data.count++;
};
instance.getValue = function() {
return privateData.get(this).count;
};
instance.reset = function(newVal = 0) {
privateData.get(this).count = newVal;
};
return instance;
}
const c1 = createCounter(5);
const c2 = createCounter(10);
console.log(c1.getValue()); // 5
console.log(c2.getValue()); // 10
c1.increment();
console.log(c1.getValue()); // 6
// privateData 不可从外部访问,c1/c2 的私有状态完全隔离
进阶:支持原型方法与 this 安全
若希望方法挂载在原型上(提升内存效率),需确保 this 指向的是 WeakMap 记录过的实例对象。常见陷阱是方法被解构调用导致 this 丢失,可用箭头函数、bind 或代理拦截规避:
- 推荐在工厂内绑定方法(简单可靠)
- 或使用
class配合 WeakMap(需确保构造函数中 set) - 避免将方法直接放在原型上后裸调用,否则
privateData.get(this)可能返回undefined
注意边界:WeakMap 不提供私有字段语义
它不能阻止开发者通过反射或调试手段间接探查(比如 DevTools 查看闭包作用域),也不像 TypeScript 的 #field 那样有语法级访问控制。它的优势在于运行时的实际隔离性与内存友好性——不是“绝对私有”,而是“按约定不可见+不可枚举+自动清理”。
真正敏感的数据仍应由服务端控制,前端 WeakMap 主要用于防止误用、增强模块契约、避免命名冲突。


















