一、js 私有属性的几种实现方式
1. _prop 从命名上来区分
- 私有属性 _name,共有属性 age
- 这种方式只是一种命名规范,告诉开发者这个属性、方法是私有的,不要调用,但终究不是强制的,如果别人要用也阻止不了。
2. proxy
- proxy 可以定义目标对象的 get、set、Object.keys 的逻辑,可以在这一层做一下逻辑判断,如果是下划线 _ 开头就不让访问,否则就可以访问 @code{12-33}
3. symbol
- symbol 是 es2015 添加的api,用于创建唯一的值。基于这个唯一的特性,我们就可以实现私有属性。 @code{36-47}
- 缺陷:可以使用 Object.getOwnPropertySymbols, 可以取到对象的所有 Symbols 属性,然后就可以拿到属性值了。
4. WeakMap
- 只能用对象作为 key,对象销毁,这个键值对就销毁 @code{50-65}
- 每个属性定义一个 WeakMap 来维护,key 为当前对象,值为属性值,get 和 set 使用 classPrivateFiledSet 和 classPrivateFiledGet 这两个方法,最终是通过 WeakMap 获取。
5. #prop
- 通过 # 的方式来标识私有属性和方法 @code{67-72}
6. ts 中 private
- 编译期的私有属性,只是用于类型检查,运行时并没有这种约束,属于伪私有
总结
通过下划线 _prop 从命名上区分
通过 proxy 来定义 get set ownKey 的逻辑
通过 Symbol 来定义唯一的属性名,不能通过 keys 拿到
通过 WeakMap 来保存所有对象的私有属性和方法
通过 #prop 最后编译成 WeakMap 的方式
通过 ts 的 private 编译期检查
伪私有:_prop、Symbol、private
真正的私有:proxy、WeakMap、#prop