Skip to content
On this page

说说 Set 和 WeakSet

js
let s = new Set([1,2,2,3])
console.log(s) // Set(3) {1, 2, 3}
s.add(4).add(5) // Set(5) {1, 2, 3, 4, 5}
s.delete(1) // Set(4) {2, 3, 4, 5}
s.has(2) // true
s.size // 4
// s.clear() // Set(0) {}
// 遍历 Set
s.forEach(item => console.log(item))
for(let item of s) {
	console.log(item)
}
for(let item of s.keys()) {
	console.log(item)
}
for(let item of s.values()) {
	console.log(item)
}
for(let item of s.entries()) {
	console.log(item[0], item[1]) // 可以看出 key 和 value 一样的
}

// 场景1:将 Set 转成 数组
Array.from(s) // [2, 3, 4, 5]

// 场景2:交集
let arr1 = [1, 2, 3]
let arr2 = [2, 3, 4]
let s1 = new Set(arr1)
let s2 = new Set(arr2)
let res1 = new Set(arr1.filter(item => s2.has(item)))
console.log(Array.from(res1))

// 场景3:差集
let res2 = new Set(arr1.filter(item => !s2.has(item)))
console.log(Array.from(res2)) // arr1 有的 arr2 没有
let res3 = new Set(arr2.filter(item => !s1.has(item)))
console.log(Array.from(res3)) // arr2 有的 arr1 没有

// ---------------------------------------- //
let ws = new WeakSet()
const obj1 = {weight: 130}
const obj2 = {eyes: 2}
ws.add(obj1)
ws.add(obj2)
ws.add({
	name: 'hello'
})
ws.add({
	age: 18
})
ws.delete({
	name: 'hello'
}) // 这样删除无效
ws.delete(obj1)
ws.has(obj2)
console.log(ws)

// WeakSet 无法遍历,当中的对象一般叫做弱引用,垃圾回收机制不考虑弱引用的引用的
let obj3 = {legs: 2}
ws.add(obj3)
obj3 = null
console.log(ws) // 好像还是能看见 obj3 ,为什么?
// 因为浏览器的垃圾回收机制是不受我们控制的,我们无法知道垃圾回收机制什么时候执行,之所以打印能出现内容,其实是因为打印的时候垃圾回收机制没有启动。所以可以使用下面的代码查看
console.log(ws.has(obj3)) // false

两者对比:都不可以存放相同重复的值(或引用);WeakSet 只能存放对象,不能存放其他类型,而 Set 可以;Set 可以循环遍历,而 WeakSet 不可以;WeakSet 是弱引用。 这里有篇文章可参考 10分钟讲明白WeakSet和WeakMap的弱引用 - 掘金 (juejin.cn)

讲讲 Map 和 WeakMap

js
let m = new Map()
let obj = { name: 'jel' }
m.set(obj, 'es')
m.set(Symbol(), 'ng')
console.log(m)
console.log(m.get(obj))
m.has(obj) // true
m.delete(obj)

let map = new Map([
	['name', 'llo'],
	['age', 18],
])
console.log(map)
console.log(map.size) // 2
console.log(map.has('name')) // true
console.log(map.get('age')) // 18
map.set('name', 'world')
// map.clear()

// 遍历
map.forEach((value, key) => {
	console.log(value, key)
})
for(let [key, value] of map) {
	console.log(key, value)
}
for(let key of map.keys()) {
	console.log(key)
}
for(let value of map.values()) {
	console.log(value)
}
for(let [key, value] of map.entries()) {
	console.log(key, value)
}

// Map 和 对象的区别
// Map 具有 size 属性,可以直接获取,对象需要遍历计算才能获取;频繁增删键值对的操作建议使用 Map 

// -------------------------------------- //
// WeakMap 键只能支持 引用类型
let wm = new WeakMap()
wm.set([], 0)
wm.set({name: 'llo'}, 18)
console.log(wm)
wm.clear() // 没有 clear 方法
wm.size // 没有 size 属性,原因是 WeakMap 不支持遍历操作
let obj = {language: 'en'}
wm.set(obj, 'english')
obj = null
console.log(wm.has(obj)) // false
// WeakMap 与 WeakSet 类似,也是弱引用

// performance.memory 可以查看内存的使用情况

带键的集合

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Keyed_collections

Released under the MIT License.