javascript中的Set和Map类总结

·  阅读 529

Set类

集合,就是一组值,与数组类似,但没有索引或顺序,不允许重复。 Set构造函数创建集合对象

let s = new Set()
// 参数必须是一个可迭代对象,可用于去重
let unique = new Set("aoidhfusw38aaaaafn")

Set方法

方法/属性说明let s = new Set([1,2,3,"4",2])
add()向集合添加元素,若添加一个数组,添加的是数组,而不是数组的元素var num = [1,2]s.add(num // [1,2,3,"4", [1,2])
size集合元素个数5
delete()删除元素,set中用===判断,删除数组和对象,必须是引用,返回布尔值,删除成功与否var tmp = [1,2]s.delete(tmp) // falses.delete(num) // true
entries()返回一个新的迭代器对象,包含set中按插入顺序排列的所有元素的值的数组,键值相等s.entries() // 结果见下图
has()判断元素是否在set中s.has(1) // true
clear()清空集合s.clear() //

Notes

Set专门为成员测试做了优化,无论集合有多少成员,has()方法都非常快,数组includes也能判断元素是否在数组中,但是执行速度随着数组大小成反比。

Set内置iteration,可以使用for/of循环枚举所有元素,可以使用...扩展操作符将集合转换为数组或参数

let sum = 0
for (let p of s) {
  sum += p
}
[...s]
Math.max(...s)

JavaScript中的Set没有索引,不能通过数组下标的方式取值,但Set并不是绝对无序的,循环枚举时,遍历元素的顺序是其添加进集合的顺序。

除了可迭代,Set类也实现了forEach方法,与数组类似。但由于没有索引,传入forEach的回调函数的第一和第二个参数都是元素的值

let product = 1
s.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]])
方法/属性说明let m = new Map([["one", 1],["two", 2]])
get()通过键获取值m.get("one) // 1
size元素数量2
set()添加/修改键值对m.set("three", 3)m.set("one", 111)
has()是否有键m.has("four") // false
delete通过键,删除键值对m.delete("one")
clear()清空Map

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的区别

  1. WeakMap的键必须是对象或数组,原始值(映射本身)不受垃圾收集控制,不能作为键
  2. WeakMap只实现了get(), set(), delete()和has()。其为不可迭代对象==>如果存在forEach等遍历访问方法,则它的键即为可访问的,也就谈不上是弱引用了。
  3. 没有size属性,因为弱映射的大小会随着对象被当成垃圾收集而改变。
  4. 主要用途:实现值与对象的关联而不导致内存泄漏。

WeakSet实现一组对象,没有存储当前对象的列表,不会妨碍这些对象被作为垃圾收集。

WeakSet与Set的区别

  1. 不允许原始值作为成员,只能是对象的集合
  2. 只实现add(),has(),delete()方法,不可迭代
  3. 没有size属性
  4. 用途:对象标记为具有特殊属性或类型,跟踪对象引用
分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改