首页>>前端>>JavaScript->javascript中的Set和Map类有何玄机?

javascript中的Set和Map类有何玄机?

时间:2023-12-01 本站 点击:0

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集合元素个数5delete()删除元素,set中用===判断,删除数组和对象,必须是引用,返回布尔值,删除成功与否var tmp = [1,2]s.delete(tmp) // falses.delete(num) // trueentries()返回一个新的迭代器对象,包含set中按插入顺序排列的所有元素的值的数组,键值相等s.entries() // 结果见下图has()判断元素是否在set中s.has(1) // trueclear()清空集合s.clear() //

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]])

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

WeakMap的键必须是对象或数组,原始值(映射本身)不受垃圾收集控制,不能作为键

WeakMap只实现了get(), set(), delete()和has()。其为不可迭代对象==>如果存在forEach等遍历访问方法,则它的键即为可访问的,也就谈不上是弱引用了。

没有size属性,因为弱映射的大小会随着对象被当成垃圾收集而改变。

主要用途:实现值与对象的关联而不导致内存泄漏。

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

WeakSet与Set的区别

不允许原始值作为成员,只能是对象的集合

只实现add(),has(),delete()方法,不可迭代

没有size属性

用途:对象标记为具有特殊属性或类型,跟踪对象引用

原文:https://juejin.cn/post/7095604733439639560


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/JavaScript/6394.html