weakmap 通过不可枚举、弱引用和作用域隔离实现私有状态封装:模块顶层定义、实例为 key、不导出变量、方法间接读写、绑定 dom 自动解耦、避免反向引用与闭包陷阱。

WeakMap 本身不提供访问控制语法,但能通过“不可枚举 + 弱引用 + 作用域隔离”三重机制,让外部代码无法直接读写组件内部状态。关键不在限制语法,而在切断所有常规访问路径。
用模块级 WeakMap 封装私有状态容器
WeakMap 必须定义在组件模块顶层(不能在构造函数或方法里重复 new),确保所有实例共享同一个映射容器,同时外部完全不可见:
- 把组件实例(如 this 或 DOM 元素)作为 key,存入一个普通对象作为 value,该对象即为私有状态池
- 这个 WeakMap 变量不导出、不挂到全局、不暴露给任何外部作用域
- 外部代码既无法遍历 WeakMap(无 keys()/values() 方法),也无法猜测键值——因为 key 是对象引用,不是字符串名
只通过原型方法间接读写,不暴露 setter
所有状态访问都封装在类的方法中,且可按需控制读写权限:
- 提供 getter 方法(如 getState()),内部调用 weakMap.get(this) 返回状态对象的副本或指定字段
- 若需只读,就不提供 setter;若需受控修改,setter 内部做校验(如检查状态流转合法性),再调用 weakMap.set(this, newState)
- 避免返回私有状态对象本身,防止外部直接修改——可用 Object.assign({}, state) 或结构化克隆
绑定 DOM 元素时自动解耦生命周期
当组件基于 DOM 元素构建(如自定义拖拽区、按钮状态机),WeakMap 的弱引用特性天然防止内存泄漏:
- 以 el 为 key 存储 { isDragging: false, lastDropTime: 0 } 等状态
- 页面移除该元素后,只要没其他强引用,对应条目自动消失,无需手动清理
- 外部脚本即使拿到 el,也无法通过 el 访问 WeakMap 中的数据——没有引用路径,等于不存在
避免常见破绽:闭包与引用陷阱
WeakMap 安全的前提是不意外创建强引用闭环:
- 私有状态对象里不要存 this 或对当前组件的反向引用(如 { owner: this }),否则会阻止 GC
- 不把函数闭包存进 WeakMap value,尤其被事件监听器长期持有的箭头函数
- 如果需要回调,优先用 .bind(this) 并在销毁时显式 removeEventListener
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











