Map&Set

概览

类型 用途 属性 方法 遍历
Set 值不重复 size add delete has clear yes
WeakSet 值不重复,且为对象,且垃圾回收不考虑此引用 no add delete has no
Map 键可以为对象 size [set get]delete has clear yes
WeakMap 键为对象,且垃圾回收不考虑此引用 no [set get] delete has no

weak 表示弱引用 垃圾回收不考虑此引用,不可遍历,没有大小(WeakMap)键或(WeakSet)值需要是对象

Set 不重复的值

  • 成员不会有重复值
1let p= new Set([1,1])//1
  • Set 函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化
1const set = new Set([1, 2, 3, 4, 4]);
2const set = new Set(document.querySelectorAll('div'));
  • 在 Set 中两个 NaN 是相等的,不同于其它,因此 Set 中 NaN 只能存在一个
1let set = new Set();
2let a = NaN;
3let b = NaN;
4set.add(a);
5set.add(b);
6set // Set {NaN}
7
8NaN===NaN //false
  • Set 常常用来数组/字符串去重
1[...new Set(array)]
2[...new Set('ababbc')].join('')
  • Set 有实例属性 size,方法 add delete has clear
1let s= new Set([1])
2s.add(2)
3s.size // 2
4s.has(1) // true
5s.delete(2);
  • Set 转换成数组 Array.from(aset)或 […aset];
  • Set 遍历方法有 keys=values(因为只有值没有键) entries forEach,默认为 values(可以 for(lex x of aset){})
 1let set = new Set(['red', 'green', 'blue']);
 2for (let item of set.keys()) {
 3  console.log(item);
 4}
 5// red green blue
 6
 7for (let item of set.entries()) {
 8  console.log(item);
 9}
10// ["red", "red"]
11// ["green", "green"]
12// ["blue", "blue"]

WeakSet 不重复的值, 弱引用, 只能放置对象, 没有 size 属性,也没办法遍历

  • 只能放对象
1const b = [3, 4];
2const ws = new WeakSet(b);
3// Uncaught TypeError: Invalid value used in weak set(…)
  • 有三个实例方法 add delete has (比 Set 少了 clear),没有 size 属性,也没办法遍历
  • WeakSet 的一个用处,是储存 DOM 节点,而不用担心这些节点从文档移除时,会引发内存泄漏

Map 可以对象作为键

  • 创建一个 Map 实例
1const map = new Map([
2  ['name', 'a'],
3  ['title', 'b']
4]);
  • 如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,布尔值 true 和字符串 true 则是两个不同的键
1{true:1,'true':2}//{'true':2}
2
3let map = new Map();
4map.set(true, 1);
5map.set('true', 2);
6map.get(true) // 1
7map.get('true') // 2
  • 实例属性 size,实例方法 set get has delete clear
1let map= new Map()
2map.set(1,1);
3map.get(1);//1
4map.has(1);//true 是否有某个键
5map.size//1
6map.delete(1)//true 成功true 失败false
7map.clear()//除所有成员,没有返回值
8
  • 遍历方法 keys values entries forEach (遍历顺序就是插入顺序), 默认遍历器接口 entries(for (let [key, value] of map) {})
 1for (let key of map.keys()) {
 2  console.log(key);
 3}
 4for (let item of map.entries()) {
 5  console.log(item[0], item[1]);
 6}
 7或者解构赋值
 8for (let [key, value] of map.entries()) {
 9  console.log(key, value);
10}
11或者默认遍历器
12for (let [key, value] of map) {
13  console.log(key, value);
14}
  • Map 转为数组 […amap]
1const myMap = new Map()
2  .set(true, 7)
3  .set({foo: 3}, ['abc']);
4[...myMap]
5// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]

WeakMap 只接受对象作为键名(null 除外),键名弱引用, 不可遍历, 没有 size 属性

  • DOM 节点作为键名
1//一旦这个 DOM 节点删除,该状态就会自动消失,不存在内存泄漏风险。
2let myElement = document.getElementById('logo');
3let myWeakmap = new WeakMap();
4myWeakmap.set(myElement, {timesClicked: 0});
5
6myElement.addEventListener('click', function() {
7  let logoData = myWeakmap.get(myElement);
8  logoData.timesClicked++;
9}, false);
  • 部署私有属性
 1const _counter = new WeakMap();
 2class Countdown {
 3  constructor(counter, action) {
 4    //内部属性_counter,是实例的弱引用,所以如果删除实例,它们也就随之消失,不会造成内存泄漏
 5    _counter.set(this, counter);
 6  }
 7  dec() {
 8    let counter = _counter.get(this);
 9    if (counter < 1) return;
10    counter--;
11    _counter.set(this, counter);
12  }
13}

Module
Event

评论