1.set
1.set
可以存储引用数据类型
2.set
中的数据都是唯一的(可以用于初始化数组,实现数组的去重)
3.Set
实现了 iterator
接口,所以可以使用扩展运算符和for…of…
进行遍历,顺序就是插入的顺序
4.Map
和Set
中对象的引用都是强类型化的,并不会允许垃圾回收。这样一来,如果Map
和Set
中引用了不再需要的大型对象
set的使用
属性
Set 结构的实例有以下属性。
Set.prototype.constructor
:构造函数,默认就是Set函数。
Set.prototype.size
:返回Set实例的成员总数。
操作方法
Set.prototype.add(value)
:添加某个值,返回 Set 结构本身。
Set.prototype.delete(value)
:删除某个值,返回一个布尔值,表示删除是否成功。
Set.prototype.has(value)
:返回一个布尔值,表示该值是否为Set的成员。
Set.prototype.clear(
):清除所有成员,没有返回值。
遍历
Set.prototype.keys()
:返回键名的遍历器
Set.prototype.values()
:返回键值的遍历器
Set.prototype.entries()
:返回键值对的遍历器
Set.prototype.forEach()
:使用回调函数遍历每个成员
let set = new Set(['red', 'green', 'blue']);
for (let item of set.keys()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.values()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.entries()) {
console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
应用
1.初始化数组()数组的去重
2.并集(Union)、交集(Intersect)和差集(Difference)。
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}
// (a 相对于 b 的)差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}
2.WeakSet
1.和Set
结构类似,也是不重复的值的集合,但WeakSet
的成员只能是对象。
2.WeakSet
中的对象都是弱引用
,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。
3.WeakSet
适合临时存放一组对象,以及存放跟对象绑定的信息。只要这些对象在外部消失,它在 WeakSet
里面的引用就会自动消失
4.ES6
规定 WeakSet
不可遍历
操作方法
和set但是注意,WeakSet
没有size
属性因为无法遍历,
WeakSet
不能遍历,是因为成员都是弱引用,随时可能消失,遍历机制无法保证成员的存在,很可能刚刚遍历结束,成员就取不到了
使用场景
1.储存 DOM
节点,而不用担心这些节点从文档移除时,会引发内存泄漏(如果js
存储一个dom
节点,当该dom
节点需要删除时,如果js
存储的dom
节点没有删除的话就会造成内存泄漏)
Map
- 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者基础类型) 都可以作为一个键或一个值。
- 一个
Map
对象在迭代时会根据对象中元素的插入顺序来进行 — 一个for...of
循环在每次迭代后会返回一个形式为[key,value]
的数组。
3.NaN
是与 NaN
相等的(虽然 NaN !== NaN
),剩下所有其它的值是根据 ===
运算符的结果判断是否相等。
Objects 和 maps 的比较
使用 Map:
储存的键不是字符串/数字/或者 Symbol 时
,选择 Map,因为 Object 并不支持
储存大量的数据时
,选择 Map,因为它占用的内存更小
需要进行许多新增/删除元素的操作时
,选择 Map,因为速度更快
需要保持插入时的顺序的话
,选择 Map,因为 Object 会改变排序
需要迭代/遍历的话
,选择 Map,因为它默认是可迭代对象,迭代更为便捷
使用 Object:
只是简单的数据结构时
,选择 Object,因为它在数据少的时候占用内存更少,且新建时更为高效
需要用到 JSON 进行文件传输时
,选择 Object,因为 JSON 不默认支持 Map
需要对多个键值进行运算时
,选择 Object,因为句法更为简洁
需要覆盖原型上的键时
,选择 Object
虽然 Map 在很多情况下会比 Object 更为高效,不过 Object 永远是 JS
中最基本的引用类型,它的作用也不仅仅是为了储存键值对。
Objects 和 maps 的比较 摘抄:https://zhuanlan.zhihu.com/p/358378689
操作方法
1.size 属性
size属性返回 Map 结构的成员总数。
2.Map.prototype.set(key, value)
set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。
3.Map.prototype.get(key)
get方法读取key对应的键值,如果找不到key,返回undefined。
4.Map.prototype.has(key)
has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
5.Map.prototype.delete(key)
delete方法删除某个键,返回true。如果删除失败,返回false。
6.Map.prototype.clear()
clear方法清除所有成员,没有返回值。
遍历
Map.prototype.keys()
:返回键名的遍历器。
Map.prototype.values()
:返回键值的遍历器。
Map.prototype.entries()
:返回所有成员的遍历器。
Map.prototype.forEach()
:遍历 Map 的所有成员。(可以使用forEach)
Map 转为对象
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
obj[k] = v;
}
return obj;
}
const myMap = new Map()
.set('yes', true)
.set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }
对象转为 Map
使用Object.entries
Object.entries()
方法返回一个给定 对象自身 可枚举属性的键值对 数组(把object转化为键值对数组)
WeakMap
WeakMap
与Map
的区别有两点。
1.WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。
2.WeakMap
的引用时弱引用,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakMap
之中
3.不能遍历,内有size属性,不支持clear()方法
使用场景
1.同WeakSet
用来存储DOM
节点
2.部署私有属性
利用弱映射,将内部属性设置为实例的弱引用对象,当实例删除时,私有属性也会随之消失,因此不会内存泄漏
参考:https://juejin.cn/post/7062921417196568607#heading-22