ES6新特性之Map、Set与WeakMap、WeakSet的区别

ES6新特性之Map、Set与WeakMap、WeakSet的区别

ES6提供了新的数据结构Set,类似于数组,不过里面不会出现重复的值

另外一个是Map,类似于对象,对象只能使用字符串作为键,而Map可以使用任意类型

回顾下Map和Set

简要总结如下:

  • Map

    • 与 Object 一样,本质上是Hash结构

    • 可以使用各种类型作为key

    • Object 只能使用字符串作为key

1
2
3
4
5
6
7
8
9
10
11
12
13
// 使用数组作为key
let o = [1,2,3]
let b = [1,2,3]
let map = new Map()
map.set(o, 'foo')
map.set(b, 'bar')
// 虽然使用了相同的数组,但数组的内存地址不一样,所以key不一样
console.log(map.get(o)) // 'foo'
console.log(map.get(b)) // 'bar'
// 而使用对象就不能用上面的方法,对象的key只能使用字符串
let obj = {
[1,2,3]: 'foo' //会报语法错误
}
  • Set
    • 与数组类似
    • 成员唯一,没有重复值
1
2
3
4
5
6
7
8
9
10
let set = new Set([1,1,1,2,3,4])

for (let item of set) {
console.log(item)
}
// 1
// 2
// 3
// 4
// 去掉了重复的1

WeakMap和WeakSet与Map和Set的主要区别就是:

  • WeakSet 对象中只能存放对象引用,不能存放原始数据(如数字 1)

  • WeakSet 对象中存储的对象值都是被弱引用的,如果没有其他的变量或属性引用这个对象值, 则这个对象值会被当成垃圾回收掉。

  • WeakMap 中的key只是对象引用,不能是 原始数据类型

  • WeakMap 持有的是每个键或值对象的弱引用,如果没有其他的变量或属性引用这个对象值, 则这个对象值会被当成垃圾回收掉。

  • WeakMap 的key和 WeakSet 的元素是不可枚举的,因为他们存储的对象都是被弱引用的,如果能被枚举,会受垃圾回收机制的影响出现不确定性的结果

举个例子

如果使用的是Map

1
2
3
const div = document.querySelector('div')
let map = new Map()
map.set(div, 'foo')

上面div是一个对象,map中以div为key,形成了对div对象的引用

如果我们不再需要这个对象,就必须手动解除引用,不然就不会对div的内存进行清理

1
2
div = null  // 不再需要这个对象
map.delete(div) // 手动解除map中的引用

而如果使用了WeakMap

1
2
3
const div = document.querySelector('div')
let weakmap = new WeakMap()
weakmap.set(div, 'foo')

如果我们不再需要这个对象,由于WeakMap是弱引用,所以垃圾回收机制会清理掉div的内存

1
2
div = null  // 不再需要这个对象
// weakmap.delete(div) 不用手动解除

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×