set 和 map
set基本用法
- set的成员的值都是唯一的,没有重复的值(对于常量来说,因为变量本身就是不相等的)
new Set()
:生成set数据结构- 参数可以是一个数组/类数组,用于初始化set
- Set实例的属性:
- Set.prototype.constructor:构造函数,默认为Set函数
- Set.prototype.size:返回set实例的成员数量
- set实例的方法:
- set.add(val):
- 添加某个值,返回set本身
- 向set加入值的时候,值不会发生类型转换
- set内部判断两个值是否相等,使用的算法是
same-value-zero equality
,类似全等运算符===
,区别在于set中NaN等于NaN
- set.delete(val):删除某个值,返回布尔值,表示是否删除成功
- set.has(val):返回布尔值,表示是否包含某个成员
- set.clear():清空set,无返回值
- set.add(val):
- 去除重复数组的方法:
- [...new Set(array)]
- Array.from(new Set(array))
- 去除重复字符串字符:[...new Set(string)].join('')
- set的遍历操作:
- keys(),values():由于set结构没有键名,所以这两者的行为是相等的,都返回set内的值,顺序为插入时的顺序
- entries():返回一个包括[键名,键值]的数组,而由于set无键名,故键名的值等于键值
- set结构默认可遍历,默认遍历器生成函数为values()方法,即:
- Set.prototype[Symbol.iterator] === Set.prototype.values
- forEach():与数组的forEach类似
- set实现并集、交集、差集:
- 假设a: new Set([1, 2, 3]); b: new Set([2, 3, 9])
- 并集:new Set([...a, ...b]) // 1, 2, 3, 9
- 交集:new Set([...a].filter(x => b.has(x))) // 2, 3
- 差集:new Set([...a].filter(x => !b.has(x))) // 1
- 修改set的结构,应该将其转为array后,然后再次转为set
WeakSet
定义:
- WeakSet结构和Set类似,表示不重复的值的集合
- WeakSet的成员只能是
对象和Symbol值
,不能是其他类型的值 - WeakSet的对象是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用(出现内存泄漏的可能低)
- 当其他对象都不再引用该对象,则垃圾回收机制会自动回收该对象占用的内存,不考虑该对象是否存在于WeakSet中
- WeakSet的引用,都不计入垃圾回收机制,适合临时存放一组对象,一级存放跟对象绑定的信息
- WeakSet内部成员的个数,取决于垃圾回收机制是否运行,运行前后可能成员个数不一样,ES6规定WeakSet是不可遍历的
创建:new WeakSet(iterable?)
:
- 其中可迭代对象参数的成员会自动转为weakset的成员,从而可以是一个对象数组
[Symbol(), {}]
,而非原始值类型元素的数组[1, false, '']
实例方法:
- WeakSet.prototype.add(value)
- WeakSet.prototype.delete(value):返回true、false
- WeakSet.prototype.has(value)
Map
前置:
- JavaScript对象本质是是键值对的集合
- 传统的对象只能用字符串当键,即使将对象作为对象的键,该键仍然会转成字符串形式,比如
new Object()
将转为[object Object]
- 传统的对象是字符串-值的对应关系
定义:
- Map类似于对象,也是键值对的集合
- Map的键可以是任意类型的值
- Map是值-值的对应关系(更完善的hash结构实现)
- Map接收一个具有Iterator接口(比如数组、Set、Map)、且每个成员都是一个双数组的数据结构作为其构造函数的参数
[['name', 'jade'], ['title', 'author']]
,其中双数组中的第一个元素作为他的键,第二个元素作为键的值
注意:
- map的set方法可以进行链式操作,返回map对象本身
- 若对同一个键(值的引用,所以此处会进行严格相等的比较)进行多次赋值,后面的值将覆盖前面的值
- 读取一个未知的键,返回undefined
- Map会将0和-0、NaN和NaN、同一个对象的引用(内存地址相同)视为同一个键
- map的默认遍历器是map.entries方法,故而
[...map]
和[...map.entries()]
两者结果相同
实例属性:
- Map.prototype.size
实例方法:
- Map.prototype.set(key, value):返回map本身
- Map.prototype.get(key):返回value || undefined
- Map.prototype.has(key)
- Map.prototype.delete(key):返回true、false
- Map.prototype.clear():清除所有成员,无返回值
- Map.prototype.forEach():遍历map,遍历顺序是插入顺序
遍历器生成函数,返回相应的遍历器(map iterator):
- Map.prototype.keys()
- Map.prototype.values()
- Map.prototype.entries()
遍历器(具有iterator接口的数据结构):
- String
- Array
- Map
- Set
- TypedArray
- arguments
- NodeList
- generator对象
操作遍历器的方式:
- 解构赋值:
[a, b] = iteratorObj
,获取迭代器的值,map获取的内容是[key, value]
的形式 - 扩展运算符:
[...iteratorObj]
,转为数组形式 yield*
配合function*
一起使用:generator = fucntion* () {yeild* iteratorObj}; iteratorOtherObj = generator()
,用于遍历迭代器- for...of:按添加时的先后顺序遍历迭代器
- Array.from
- Map(), Set(), WeakMap(), WeakSet()
- Promise.all(iteratorObj)
- Promise.race(iteratorObj)
WeakMap
定义:
- WeakMap和Map结构类似,用于生成键值对的集合
- WeakMap只接受对象、symbol值作为键名
- WeakMap键名指向的对象,不计入垃圾回收机制,键名引用的对象是弱引用,只要对象的引用被清除,垃圾回收机制就会释放该对象所占用的内存
- WeakMap弱引用仅针对键名,键名的引用若重新赋值,读取时则可能获取不到预期的结果。不针对键值,即使键值所对应的内容重新赋值了,读取时依然是赋值之前的内容
实例方法:
- get()
- set()
- has()
- delete()
用途(防止内存泄漏):
- 将dom作为他的键,dom删除,键也会同时删除
- 保存类的私有属性,实例删除,该结构也随之消失
注意:
- weakmap弱引用的只是键名,而非键值