0%

ES6:WeakSet,Set,Map,WeakMap

ES6:WeakSet,Set,Map,WeakMap

Set 是一种叫做集合的数据结构,Map 是一种叫做字典的数据结构。

Set

  1. Set是一个集合,里面的值都是唯一的,没有重复的。
  2. Set中可以是任何数据类型,并且添加数据时会进行严格比较,重复数据无法加入。
  3. Set 本身是一个构造函数,用来生成 Set 数据结构。
  4. Set 函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。
  5. Set 对象允许你存储任何类型的值,无论是原始值或者是对象引用。它类似于数组,但是成员的值都是唯一的,没有重复的值。
1
2
3
4
5
const s = new Set()[2, 3, 5, 4, 5, 2, 2].forEach((x) => s.add(x))
for (let i of s) {
console.log(i)
}
// 2 3 5 4
Set 中的特殊值

Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。有几个特殊值需要特殊对待:

  1. +0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复;
  2. undefined 与 undefined 是恒等的,所以不重复;
  3. NaN 与 NaN 是不恒等的,但是在 Set 中认为 NaN 与 NaN 相等,所有只能存在一个,不重复。
Set 的属性

size:返回集合所包含元素的数量。

1
2
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5])
items.size // 5
Set 实例对象的方法
  1. add(value):添加某个值,返回 Set 结构本身(可以链式调用)。
  2. delete(value):删除某个值,删除成功返回 true,否则返回 false。
  3. has(value):返回一个布尔值,表示该值是否为 Set 的成员。
  4. clear():清除所有成员,没有返回值。
1
2
3
4
5
6
7
8
s.add(1).add(2).add(2)
// 注意2被加入了两次
s.size // 2
s.has(1) // true
s.has(2) // true
s.has(3) // false
s.delete(2)
s.has(2) // false
遍历方法
  1. keys():返回键名的遍历器。
  2. values():返回键值的遍历器。
  3. entries():返回键值对的遍历器。
  4. forEach():使用回调函数遍历每个成员。

由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以 keys 方法和 values 方法的行为完全一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let set = new Set(['red', 'green', 'blue'])

for (let item of set.keys()) {
console.log(item)
}
// red
// green
// blue

for (let item of set.values()) {
console.log(item)
}
// red
// green
// blue

for (let item of set.entries()) {
console.log(item)
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
Array 和 Set 对比
  1. Array 的 indexOf 方法比 Set 的 has 方法效率低下
  2. Set 不含有重复值(可以利用这个特性实现对一个数组的去重)
  3. Set 通过 delete 方法删除某个值,而 Array 只能通过 splice。两者的使用方便程度前者更优
  4. Array 的很多新方法 map、filter、some、every 等是 Set 没有的(但是通过两者可以互相转换来使用)
Set 的应用

1、Array.from 方法可以将 Set 结构转为数组。

1
2
const items = new Set([1, 2, 3, 4, 5])
const array = Array.from(items)

2、数组去重

1
Array.from(new Set(array))

3、数组的map和filter方法也可以间接用于set

1
2
3
4
5
6
set = new Set([...set].map((x) => x * 2))
// 返回Set结构:{2, 4, 6}

let set = new Set([1, 2, 3, 4, 5])
set = new Set([...set].filter((x) => x % 2 == 0))
// 返回Set结构:{2, 4}

4、实现并集 (Union)、交集 (Intersect) 和差集

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

// 并集
new Set([...a, ...b])
// Set {1, 2, 3, 4}

// 交集
new Set([...a].filter((x) => b.has(x)))
// set {2, 3}

// 差集
new Set([...a].filter((x) => !b.has(x)))
// Set {1}
new Set([...b].filter((x) => !a.has(x)))
// Set {4}

WeakSet

  1. 弱引用Set。只能存储对象,不能存储其他类型。且只保持对其中对象的弱引用,若外部无对此对象的引用,或者对象被删除,则WeakSet中将不再有此对象。
  2. 因为成员都是弱引用,随时可能消失,遍历不能保证成员的存在。所以 WeakSet 不能遍历。
  3. WeakSet 结构与 Set 类似,也是不重复的值的集合。
  4. 成员都是数组和类似数组的对象,若调用 add() 方法时传入了非数组和类似数组的对象的参数,就会抛出错误。
  5. 成员都是弱引用,可以被垃圾回收机制回收,可以用来保存 DOM 节点,不容易造成内存泄漏。
  6. WeakSet 不可迭代,因此不能被用在 for-of 等循环中。
  7. WeakSet 没有 size 属性。

Map

Map是一个键值对。

Map与Object的区别是:

  1. Object的key只能是String和Symbol类型,而Map的key可以是任何基本类型(String, Number, Boolean, undefined, NaN….)或对象类型(Map, Set, Object, Function , Symbol , null….)
  2. Map有size属性,可以方便的获取Map的长度,但是Object无法直接获取长度

Map 的属性:

  1. size: 返回集合所包含元素的数量

Map 对象的方法:

  1. set(key, val): 向 Map 中添加新元素
  2. get(key): 通过键值查找特定的数值并返回
  3. has(key): 判断 Map 对象中是否有 Key 所对应的值,有返回 true,否则返回 false
  4. delete(key): 通过键值从 Map 中移除对应的数据
  5. clear(): 将这个 Map 中的所有元素删除
1
2
3
4
5
6
7
8
9
const m = new Map()
const o = {
p: 'Hello World'
}
m.set(o, 'content')
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false

WeakMap

弱引用Map。WeakMap有如下特点:

  1. WeakMap的key只能是对象,不能是基本类型,且对象不计入垃圾回收机制
  2. WeakMap没有keys、values、entries、size方法
  3. WeakMap没有遍历操作,无法遍历

WeakMap和WeakSet的作用,可以用来存储DOM节点,保持与DOM节点相关的数据,当DOM节点被删除后,集合中的数据自动删除,
这样就不必担心移除DOM节点时的内存泄漏了。

转发:https://segmentfault.com/a/1190000022936727

  • 本文作者: David Xue
  • 本文链接: https://xdw-h.github.io/14/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!