通过WeakMap实现私有类变量

主要利用 WeakMap(弱映射)的 “不可迭代键” 特性实现

  • 因为 WeakMap 中 键值对 任何时候都可能被销毁,所以没必要提供迭代其键值对的能力
  • 因为不可迭代,所以也不能在不知道对象引用的情况下从 WeakMap 中取值
  • 之所以限制只能使用 键值对 作为键,是为了保证只有通过键值对的引用才能取得值
  • 如果允许原始值,那就没法区分初始化时使用的字符串字面量和初始化之后的一个相等字符串了

基于上述特性,可以实现真正的私有变量的一种新方式,前提很明确,私有变量会存储在 WeakMap 中,以对象实例为键,以私有成员的字典为值。

通过闭包,维护一个 WeakMap 集合,维护私有变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const User = (() => {
const wm = new WeakMap()

class User {
constructor (id) {
this.idProperty = Symbol('id')
this.setId(id)
}

setPrivate (property, value) {
// 把当前实例当作键值,存储对应对象,存储对应 value
const privateMembers = wm.get(this) || {}
privateMembers[property] = value
wm.set(this, privateMembers)
}

getPrivate (property) {
return wm.get(this)[property]
}

setId (id) {
this.setPrivate(this.idProperty, id)
}

getId () {
return this.getPrivate(this.idProperty)
}
}

return User
})()