Set/WeakSet/Map/WeakMap的简介与不同

Set是类数组,成员唯一,可遍历
WeakSet成员唯一且只能是对象,弱引用,不占引用数, 不能遍历(例子:保证Foo的实例方法只在Foo的实例上调用,把this add到WeakSet实例中,调用方法时判断this 是否在WeakSet实例中)
Map是类对象,key可以是非字符串,设置时不会转类型,1 与 ‘1’ 是两个key,key为对象时,以内存地址为准,可遍历
WeakMap是类对象,key只能是对象,弱引用,不占用引用数(防止内存泄漏,例子:把可能会消失的dom写道WeakMap实例中,防止内存泄漏) No.4. Set/WeakSet/Map/WeakMap - 图1

WeakSet应用1-保证Foo的实例方法,只能在Foo的实例上调用

新建了一个foo:WeakSet,在Foo这个类实例化时把this加入到foo中,调用method时判断this是否在foo中
这样就保证了method在Foo实例中调用

  1. const foos = new WeakSet()
  2. class Foo {
  3. constructor() {
  4. foos.add(this)
  5. }
  6. method () {
  7. if (!foos.has(this)) {
  8. throw new TypeError('Foo.prototype.method 只能在Foo的实例上调用!');
  9. }
  10. }
  11. }

部署私有属性,而不担心内存泄漏(WeakMap应用1)

Countdown类的两个内部属性_counter_action,是实例的弱引用,所以如果删除实例,它们也就随之消失,不会造成内存泄漏。

  1. const _counter = new WeakMap();
  2. const _action = new WeakMap();
  3. class Countdown {
  4. constructor(counter, action) {
  5. _counter.set(this, counter);
  6. _action.set(this, action);
  7. }
  8. dec() {
  9. let counter = _counter.get(this);
  10. if (counter < 1) return;
  11. counter--;
  12. _counter.set(this, counter);
  13. if (counter === 0) {
  14. _action.get(this)();
  15. }
  16. }
  17. }
  18. const c = new Countdown(2, () => console.log('DONE'));
  19. c.dec()
  20. c.dec()
  21. // DONE