【JavaScript】Set、Map、WeakSet、WeakMap
Set、Map、WeakSet、WeakMap
Set
Set
对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用
let a = new Set()
a.add(1)
// 输出 Set(1) {1}
a.add(2)
// 输出 Set(2) {1, 2}
a.add(2)
// 输出 Set(2) {1, 2}
Set
可以对数组进行去重,对象除外,并不能判断对象是否重复
Set 内部中用的是===来判断的
let b = new Set()
b.add({ val: 1 })
b.add({ val: 1 })
// 输出 Set(2) {{val:1}, {val:1}}
- 成员唯一、无序且不重复
[value, value]
,键值与键名是一致的(或者说只有键值,没有键名)- 可以遍历,方法有:
add
、delete
、has
、clear
、entries
、forEach
、keys
、values
Set
也能用来保存NaN
和undefined
, 如果有重复的NaN
,Set
会认为就一个NaN
(实际上NaN!=NaN
)
WeakSet
- 成员都是对象;
- 成员都是弱引用,可以被垃圾回收机制回收,可以用来保存
DOM
节点,不容易造成内存泄漏; - 不能遍历,方法有
add
、delete
、has
Set 与 WeakSet 总结
// Set '数据类型',只能放数组
let setArr = new Set(['abing', 'ABing', 'abing'])
// 追加
setArr.add('hahaha')
// 删除
setArr.delete('abing')
// 查找
console.log(setArr.has('ABing')) // true
// set中不允许出现重复值
console.log(setArr) // Set { 'ABing', 'hahaha' }
// 删除所有
// setArr.clear()
// console.log(setArr) // Set {}
// 循环打印
for (let item of setArr) {
console.log(item) // ABing hahaha
}
setArr.forEach(item => console.log(item)) // ABing hahaha
// 获取长度
console.log(setArr.size) // 2
// WeakSet 可以放对象
// let weakObj = new WeakSet({ a: 'abing', b: 'abing', c: 'ABing' }) // object is not iterable
let weakObj = new WeakSet()
let obj = { a: 'abing', b: 'abing', c: 'ABing' }
let obj1 = { a: 'abing', b: 'abing', c: 'ABing' }
weakObj.add(obj)
weakObj.add(obj1)
console.log(weakObj) // 全部打印(内存空间不同)
let weakObj = new WeakSet()
let obj = { a: 'abing', b: 'abing', c: 'ABing' }
let obj1 = obj
weakObj.add(obj)
weakObj.add(obj1)
console.log(weakObj) // 只打印一个(内存空间相同)
Map
- 本质上是键值对的集合,类似集合;
- 可以遍历,方法很多,可以跟各种数据格式转换。
const data = {}
const element = document.getElementsByTagName('div')[0]
data[element] = 'metadata'
console.log(data['[object HTMLDivElement]']) // metadata
// 上面代码原意是将一个Dom节点作为对象data的键,但是由于对象只接受字符串作为键名,所以element被自动的转为了字符串。
实例属性与操作方法
size
属性(size
属性返回Map
结构的成员总数)
const map = new Map()
map.set('foo', 1).set('bar', 2)
console.log(map.size) //2
- set(key,value)
set
方法设置键名 key
对应的键值 value
,然后返回整个 Map
结构,如果 key
已经有值,则键值会被更新,否则就新生成该键。
const m = new Map()
m.set('edition', 6)
m.set(123, 'standard')
m.set(undefined, 'nah')
set 方法返回的是当前的 Map 对象,因此可以采用链式写法。
const map = new Map()
map.set('foo', 1).set('bar', 2).set('baz', 3)
console.log(map)
- get(key)
get
方法读取 key
对应的键值,如果找不到 key
,返回 undefined
。
const map = new Map()
const hello = () => {
console.log('hello')
}
map.set(hello, 'Hello')
console.log(map.get(hello)) // Hello
- has(key)
has
方法返回一个布尔值,表示某个键是否在当前 Map
对象中。
const map = new Map()
map.set('foo', 1)
console.log(map.has('foo')) // true
console.log(map.has('bar')) // false
- delete(key)
delete
方法删除某个键,返回 true
,如果删除失败,返回 false
。
const map = new Map()
map.set('foo', 1)
console.log(map.delete('foo')) // true
console.log(map.delete('foo')) // false
- clear()
clear
方法清除所有成员,没有返回值。
const map = new Map()
map.set('foo', 1).set('baz', 2)
console.log(map.size) // 2
map.clear()
console.log(map.size) // 0
遍历方法
Map
结构原生提供是三个遍历器生成函数和一个遍历方法。
keys()
:返回键名的遍历器。values()
:返回键值的遍历器。entries()
:返回所有成员的遍历器。forEach()
:遍历Map
的所有成员。
WeakMap
Weakmap
结构与Map
结构类似,也是用于生成键值的集合。
WeakMap
可以使用 Set
方法添加成员。
const wm1 = new WeakMap()
const key = { foo: 1 }
wm1.set(key, 2)
console.log(wm1.get(key)) // 2
WeakMap
也可以接受一个数组,作为构造函数的参数。
const k1 = [1, 2, 3]
const k2 = [4, 5, 6]
const wm = new WeakMap([
[k1, 'foo'],
[k2, 'bar'],
])
console.log(wm.get(k2)) // bar
WeakMap
与 Map
有两点区别。
- 第一:和
WeakSet
一样,WeakMap 只接受对象作为键名(null
除外),不接受其他类型的值作为键名。 - 第二:
WeakSet
的键名所指的对象,不计入垃圾回收机制。
Map 总结
// Map
// json数据类型
let json = {
name: 'ABing',
age: 20,
}
console.log(json.name)
// =>
let map = new Map()
// 增加属性(k-v值可以灵活配置)
map.set(json, 'im')
console.log(map) // Map { { name: 'ABing', age: 20 } => 'im' }
map.set('ABing', json)
console.log(map) // Map {{ name: 'ABing', age: 20 } => 'im','ABing' => { name: 'ABing', age: 20 }}
console.log(map.keys()) // [Map Iterator] { { name: 'ABing', age: 20 }, 'ABing' }
console.log(map.values()) // [Map Iterator] { 'im', { name: 'ABing', age: 20 } }
console.log(map.entries()) // [Map Entries] {[ { name: 'ABing', age: 20 }, 'im' ],[ 'ABing', { name: 'ABing', age: 20 } ]}
// 增删查
// get
console.log(map.get('ABing')) // { name: 'ABing', age: 20 }
console.log(map.get(json)) // im
// delete
map.delete(json)
console.log(map) // Map { 'ABing' => { name: 'ABing', age: 20 } }
// 删除全部
map.clear()
console.log(map) // Map {}
// size
console.log(map.size) // 0
// has
map.set('ABing', json)
console.log(map.has('ABing')) // true
WeakMap 总结
- 只接受对象最为键名(
null
除外),不接受其他类型的值作为键名; - 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的;
- 不能遍历,方法有
get
、set
、has
、delete
。
详见:https://blog.csdn.net/c__dreamer/article/details/82182649