0%

ES6 的 Map Set WeakMap WeakSet 最大的特性与区别

Set

  • ES6 新增数据结构,类似数组,成员是唯一的,可以存放各种数据类型
  • 可以遍历
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
let a = {}
let b = a
let c = []
let d = c
let s = new Set([
1,
1,
'2',
'2',
Symbol(1),
1n,
a,
b, //a,b为同一个对象,只保留一个
c,
d, //a,b为同一个数组,只保留一个
[],
{},
NaN,
NaN, //即使两个NaN也只保留一个
function () {},
null,
undefined,
])
console.log(s.size) //12

WeakSet

  • 与 Set 类似,不重复的值的集合
  • 只能储存对象,WeakSet 中的对象是被 弱引用的,当其他地方没有引用到该对象时,垃圾回收机制不考虑 WeakSet 对该对象的引用,会回收掉该对象。
  • WeakSet 不能遍历,他里面的对象随时可能会消失
  • 没有 size 属性,不能获取到 WeakSet 的长度,不可遍历
  • 可以用来储存 DOM 节点,而不用担心这些节点从文档移除时,引发内存泄漏。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let a = { 1: 1 }
let b = a
let c = [1, 2]
let d = c
let s = new WeakSet([
a,
b,
c,
d,
[],
{}, //由于没有其他的引用s 中不会保留这两个对象
])
console.log(s)
/*
WeakSet {Array(0), {…}, {…}, Array(2)}
[[Entries]]
0: Object
1: Array(2)
__proto__: WeakSet
*/

Map

  • 键值对的集合,键唯一,可以是任何数据类型,可遍历
  • JS 对象的键只能是字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
let a = {}
let b = a
let c = []
let d = c
let m = new Map()
m.set(1, 1)
.set('1', '1')
.set(a, a)
.set(b, b)
.set(c, c)
.set(d, d)
.set(NaN, NaN)
.set(null, null)
.set(undefined, undefined)
.set(
function () {},
function () {}
)
.set({}, {})
.set(new Map(), {})
console.log(m.size) //12
console.log(m) //12
/*
Map(10) {1 => 1, "1" => "1", {…} => {…}, Array(0) => Array(0), NaN => NaN, …}
[[Entries]]
0: {1 => 1}
1: {"1" => "1"}
2: {Object => Object}
3: {Array(0) => Array(0)}
4: {NaN => NaN}
5: {null => null}
6: {undefined => undefined}
7: {function(){} => function(){}}
8: {Object => Object}
9: {Map(0) => Object}
size: (...)
__proto__: Map

*/

WeakMap

  • 键值对的集合,键唯一,只能是对象null 除外)
  • 值可以是任何数据
  • 和 WeakSet 类似,当其中的键没有其他地方引用时会被回收
  • 可以用来对 DOM 节点的事件绑定。
  • 不可遍历
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let a = {}
let b = a
let c = []
let d = c
let m = new WeakMap()
m.set(a, a)
.set(b, b)
.set(c, c)
.set(d, d)
.set(
function () {},
function () {}
) //没有其他地方的引用,被回收
.set({}, {}) //没有其他地方的引用,被回收
.set(new Map(), {}) //没有其他地方的引用,被回收
console.log(m)
/*
WeakMap {{…} => {…}, Map(0) => {…}, {…} => {…}, Array(0) => Array(0), ƒ => ƒ}
[[Entries]]
0: {Object => Object}
1: {Array(0) => Array(0)}
__proto__: WeakMap
*/