【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],键值与键名是一致的(或者说只有键值,没有键名)
  • 可以遍历,方法有:adddeletehasclearentriesforEachkeysvalues
  • Set 也能用来保存 NaNundefined, 如果有重复的 NaNSet 会认为就一个 NaN(实际上 NaN!=NaN)

WeakSet

  • 成员都是对象;
  • 成员都是弱引用,可以被垃圾回收机制回收,可以用来保存 DOM 节点,不容易造成内存泄漏;
  • 不能遍历,方法有 adddeletehas

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

WeakMapMap 有两点区别。

  • 第一:和 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 除外),不接受其他类型的值作为键名;
  • 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的;
  • 不能遍历,方法有 getsethasdelete

详见:https://blog.csdn.net/c__dreamer/article/details/82182649

posted @ 2020-06-10 11:35  [ABing]  阅读(132)  评论(0编辑  收藏  举报