learn icon indicating copy to clipboard operation
learn copied to clipboard

ES6 系列之 WeakMap

Open yangtao2o opened this issue 4 years ago • 0 comments

ES6 系列之 WeakMap

WeakMap 特性

1.WeakMap 只接受对象作为键名

const map = new WeakMap();
map.set(1, 2);
// Uncaught TypeError: Invalid value used as weak map key
map.set(null, 2);
// Uncaught TypeError: Invalid value used as weak map key

2.WeakMap 的键名所引用的对象是弱引用

就是 WeakMaps 保持了对键名所引用的对象的弱引用,即垃圾回收机制不将该引用考虑在内。只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。也就是说,一旦不再需要,WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用。

也正是因为这样的特性,WeakMap 内部有多少个成员,取决于垃圾回收机制有没有运行,运行前后很可能成员个数是不一样的,而垃圾回收机制何时运行是不可预测的,因此 ES6 规定 WeakMap 不可遍历

所以 WeakMap 不像 Map,一是没有遍历操作(即没有 keys()、values()和 entries()方法),也没有 size 属性,也不支持 clear 方法,所以 WeakMap 只有四个方法可用:get()、set()、has()、delete()

WeakMap 应用

1.在 DOM 对象上保存相关数据

let wm = new WeakMap(),
  element = document.querySelector(".element");
wm.set(element, "data");

let value = wm.get(elemet);
console.log(value); // data

element.parentNode.removeChild(element);
element = null;

2.数据缓存

const cache = new WeakMap();
function countOwnKeys(obj) {
  if (cache.has(obj)) {
    console.log("Cached");
    return cache.get(obj);
  } else {
    console.log("Computed");
    const count = Object.keys(obj).length;
    cache.set(obj, count);
    return count;
  }
}

3.数据缓存

const privateData = new WeakMap();

class Person {
  constructor(name, age) {
    privateData.set(this, { name: name, age: age });
  }

  getName() {
    return privateData.get(this).name;
  }

  getAge() {
    return privateData.get(this).age;
  }
}

export default Person;

原文链接:ES6 系列之 WeakMap

yangtao2o avatar Apr 06 '20 05:04 yangtao2o