1)Set
成员唯一、无序且不重复;
[value, value],键值与键名是一致的(或者说只有键值,没有键名);
可以遍历,方法有:add、delete、has、size、clear。
2)WeakSet
成员都是对象;
成员都是弱引用,可以被垃圾回收机制回收,可以用来保存DOM节点,不容易造成内存泄漏;
不能遍历,方法有 add、delete、has。
3)Map
本质上是键值对的集合,类似集合;
可以遍历,方法很多,可以跟各种数据格式转换。
let myMap = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
])
myMap
[object Map] { ... }
myMap.get(1)
"one"
[...myMap]
[[1, "one"], [2, "two"], [3, "three"]]
myMap.keys()
[object Map Iterator] { ... }
4)WeakMap
只接受对象作为键名(null 除外),不接受其他类型的值作为键名;
键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的;
- 没有size
- get、set、has、delete、没有clear
- 不能遍历
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakMap
WeakMap 不会阻止垃圾回收机制对对象的回收
map是强引用, weakmap是弱引用
应用: WeakMap缓存计算结果
// cache.js
let cache = new WeakMap();
function process(person) {
if (!cache.has(person)) {
let score = 98; // clac
cache.set(person, score);
}
return cache.gget(person)
}
// index.js
let p1 = {name: 'Jack'}
let s1 = process(p1);
// need remove p1
p1 = null;
[实践] node gc对比map 和 weakmap
// node --expose-gc index.js
global.gc();
console.log(process.memoryUsage().heapTotal.toLocaleString());
// let cache = new WeakMap();
let cache = new Map();
let k1 = new Array(1024 * 1024);
cache.set(k1, null);
global.gc();
console.log(process.memoryUsage().heapTotal.toLocaleString());
k1 = null;
// delete k1;
// console.log(Object.keys(cache)); []
global.gc();
console.log(process.memoryUsage().heapTotal.toLocaleString());
初始内存 | 新增 |
减小key后的内存 | ||
---|---|---|---|---|
map | 5,881,856 | 14,278,656 | 16,375,808 | |
weakmap | 5,881,856 | 14,278,656 | 7,979,008 |