Set类
集合,就是一组值,与数组类似,但没有索引或顺序,不允许重复。 Set构造函数创建集合对象
let s = new Set()// 参数必须是一个可迭代对象,可用于去重let unique = new Set("aoidhfusw38aaaaafn")
Set方法
Notes
Set专门为成员测试做了优化,无论集合有多少成员,has()方法都非常快,数组includes也能判断元素是否在数组中,但是执行速度随着数组大小成反比。
Set内置iteration,可以使用for/of循环枚举所有元素,可以使用...扩展操作符将集合转换为数组或参数
let sum = 0for (let p of s) { sum += p}[...s]Math.max(...s)
JavaScript中的Set没有索引,不能通过数组下标的方式取值,但Set并不是绝对无序的,循环枚举时,遍历元素的顺序是其添加进集合的顺序。
除了可迭代,Set类也实现了forEach方法,与数组类似。但由于没有索引,传入forEach的回调函数的第一和第二个参数都是元素的值
let product = 1s.forEach(n => {product *= n})
常用:数组去重,字符串去重/分割
[...s]new Set("firefox") // ["f", "i", "r", "e", "o", "x"]
Map类
Map对象表示一组被称为键的值,键值对--映射,映射类似于数组,映射速度也很快,没有数组的索引快,并且允许任何值作为“索引”(key)。任何js值都可以作为键,键的类型判断是===,与set一样
Map()构造函数创建对象
let m = new Map()let n = new Map([ ["one", 1], ["two", 2]])
构造函数的参数必须为可迭代对象。
let o = {x:1, y:2} // object,不可迭代let p = new Map(Object.entries(o)) // 相当于new Map([["x", 1], ["y", 2]])
Notes
链式调用:m.set("one",1).set("two", 2).set("three", 3)
以数组/对象为键,m.set({}, 1).set({}, 2) // m.size =>2,两个对象的引用不同可作为不同的键。且m.get({}) => undefined,因为{}不在键中
m.set(m, undefined) // 把映射自身映射到undefined ,结果见下图
Map内置iteration,迭代的每个元素是一个有两个元素的数组, for/of 常用解构赋值
[...m] // [["one", 1], ["two", 2]]for (let [key, value] of m) { console.log(key,value)} // one 1// two 2
与Set类似,Map也是按插入顺序迭代的。获取键/值/键值
[...m.keys()] // ["one", "two][...m.vlaues()] // [1, 2][...m.entries()] // [["one", 1],["two", 2]] 等价于[...m]
forEach()
m.forEach((value, key) => {}) // 值在前,键在后,==> 值在前,索引在后
WeakMap类 & WeakSet类
WeakMap(弱映射)是Map类的变体,它不会阻止键值被当做垃圾收集。常规的Map对自己的键值保持着强引用,即使对它们的其他引用不存在了,仍然可以通过映射访问这些值。相对而言WeakMap保持着对键值的弱引用,因此无法通过WeakMap访问这些键,进而Weakmap并不影响键值被回收。
WeakMap 与Map的区别
WeakMap的键必须是对象或数组,原始值(映射本身)不受垃圾收集控制,不能作为键
WeakMap只实现了get(), set(), delete()和has()。其为不可迭代对象==>如果存在forEach等遍历访问方法,则它的键即为可访问的,也就谈不上是弱引用了。
没有size属性,因为弱映射的大小会随着对象被当成垃圾收集而改变。
主要用途:实现值与对象的关联而不导致内存泄漏。
WeakSet实现一组对象,没有存储当前对象的列表,不会妨碍这些对象被作为垃圾收集。
WeakSet与Set的区别
不允许原始值作为成员,只能是对象的集合
只实现add(),has(),delete()方法,不可迭代
没有size属性
用途:对象标记为具有特殊属性或类型,跟踪对象引用
原文:https://juejin.cn/post/7095604733439639560