set & map

先总结,

  • set和map 都是ES6新数据结构,都是可迭代对象。
  • set类似数组但没有重复成员,map类似对象,但键名可以是各种类型的值不限于字符串。
  • Set,Map的构造函数都可以传入一个数组
  • Set/Map 可以遍历,方法有 keys/values/entries, 相同方法clear/delete/has, set特有add, map特有set/get

  • weakSet的成员必须都是对象,weakMap的键名必须都是对象,这些对象都是弱引用,不在js垃圾回收机制中,即外部对象的其他引用被解除后,这些成员也会跟着消失,内存被回收。

  • weakSet/weakMap不能遍历,没有size属性

Set

  • 成员唯一、无序且不重复
  • [value, value],键值与键名是一致的(或者说只有键值,没有键名)
  • 可以遍历,方法有:add、delete、has

WeakSet

  • 成员都是对象
  • 成员都是弱引用,可以被垃圾回收机制回收,可以用来保存DOM节点,不容易造成内存泄漏
  • 不能遍历,方法有add、delete、has

Map

  • 本质上是键值对的集合,类似集合
  • 可以遍历,方法很多可以跟各种数据格式转换

WeakMap

  • 只接受对象作为键名(null除外),不接受其他类型的值作为键名
  • 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的
  • 不能遍历,方法有get、set、has、delete

Set使用场景

数组去重

1
2
3
4
5
6
7
function filter1(arr){
return [...new Set(arr)]
}

function filter2(arr){
return Array.from(new Set(arr))
}

并集(Union)、交集(Intersect)和差集(Difference)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var a = new Set([1,2,3])
var b = new Set([2,3,4])

function getUnion(set1, set2){
return new Set([...set1,...set2])
}

function getIntersect(set1, set2){
return [...set1].filter((x)=>set2.has(x))
}

function getDifference(set1, set2){
return [...set1,...set2].filter((x)=> !set2.has(x)|| !set1.has(x))
}

WeakSet

首先,WeakSet 的成员只能是对象,而不能是其他类型的值。
其次,WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。

WeakSet 与 Set 在 API 上的区别主要是两个,一是没有遍历操作(即没有keys()、values()和entries()方法),也没有size属性。
因此,WeakMap只有四个方法可用:add()、has()、delete()。

Map

由上可知,Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。这就解决了同名属性碰撞(clash)的问题,我们扩展别人的库的时候,如果使用对象作为键名,就不用担心自己的属性与原作者的属性同名。

WeakMap 特点 & 使用场景

因此,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。也就是说,一旦不再需要,WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用
注意,WeakMap 弱引用的只是键名,而不是键值。键值依然是正常引用。

WeakMap与Map的区别有两点。

  • WeakMap只接受对象作为键名(null除外)
  • WeakMap的键名所指向的对象,不计入垃圾回收机制, 都是弱引用。只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。也就是说,一旦不再需要,WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用

WeakMap的设计目的在于,有时我们想在某个对象上面存放一些数据,但是这会形成对于这个对象的引用。一旦不再需要这个对象,我们就必须手动删除这个引用, 设置为null。如果你要往对象上添加数据,又不想干扰垃圾回收机制,就可以使用 WeakMap。

WeakMap 与 Map 在 API 上的区别主要是两个,一是没有遍历操作(即没有keys()、values()和entries()方法),也没有size属性。
因此,WeakMap只有四个方法可用:get()、set()、has()、delete()。