更多的集合类型
# 更多的集合类型
# set
set
用于存放不重复的数据集合。
创建方式:var set = new Set()
如果传入的数组中有重复数据,回默认去重
var arr = [1,1,2,3,4,5,5]
var set = new Set(arr);
console.log(set) // [1,2,3,4,5]
# set操作
add(data)
向set
集合的末尾添加数据。(如果数据已存在于 set 集合中,则不会再添加一项。)set
集合判断数据相同是使用Object.is()
(但是除了 +0 与 -0)
delete(data) 删除集合中的
data
clear() 清空集合
has(data) 判断
set
集合中是否存在data
数据。size 得到集合中的成员数量。不允许赋值。
# set实现
class MySet {
constructor(iterator = []) {
// 判断是否是可迭代的对象
if (typeof iterator[Symbol.iterator] != "function") {
throw new TypeError("你提供的不是一个可迭代对象!");
}
this._datas = [];
for (const item of iterator) {
this.add(item);
}
}
add(data) {
if (!this.has(data)) {
this._datas.push(data);
}
}
has(data) {
for (const item of this._datas) {
if (this.isEqual(data, item)) {
return true;
}
}
return false;
}
delete(data) {
for (let i = 0; i < this._datas.length; i++) {
if (this.isEqual(data, this._datas[i])) {
this._datas.splice(i, 1);
return true;
}
}
return false;
}
clear() {
this._datas.length = 0;
}
isEqual(data1, data2) {
if (data1 == 0 && data2 === 0) {
return true;
}
return Object.is(data1, data2);
}
*[Symbol.iterator](){
for(const item of this._datas){
yield item;
}
}
get size(){
return this._datas.length;
}
}
# Map集合
map
集合专门用于存储多个键值对数据。
使用对象存储有以下问题:
- 键名只能是字符串
- 获取数据的数量不方便
- 键名容易和原型上的名称冲突
# 如何创建 Map
const map = new Map() // 创建一个空的 Map
初始化Map需要传入一个数组,数组内成员为一个长度为2的数组,第一项为键名,第二项为键值。
const initMap = new Map([['a',1],['b',2],['c',3]]) //
# 操作
- size 获取 Map 的键值对的数量。
- set(键,值) 设置一个键值对,键和值可以是任意类型。
- 如果键存在,则修改。
- 如果键不存在,则增加。
- 比较键的方式和 Set 相同。均使用 Object.is 判断是否相同。
- get(键) 根据键名得到对应的值。
- has(键) 判断键是否存在。
- delete(键) 删除指定的键。
# Map实现
class MyMap {
constructor(iterator = []) {
if (typeof iterator[Symbol.iterator] != "function") {
throw new TypeError(iterator + "不是可迭代对象");
}
this._datas = [];
for (const item of iterator) {
if (typeof item[Symbol.iterator] != "function") {
throw new TypeError(item + "不是可迭代对象");
}
const ite = item[Symbol.iterator]()
const key = ite.next().value;
const value = ite.next().value;
this.set(key, value);
}
}
_getObj(key) {
for (const item of this._datas) {
if (this.isEqual(item.key, key)) {
return item;
}
}
return undefined;
}
isEqual(data1, data2) {
if (data1 === 0 && data2 === 0) {
return true;
}
return Object.is(data1, data2);
}
set(key, value) {
const obj = this._getObj(key);
if (obj) {
obj.value = value;
} else {
this._datas.push({ key, value });
}
}
has(key) {
return !!this._getObj(key);
}
get(key){
const obj = this._getObj(key);
if(obj){
return obj.value;
}
}
delete(key){
for(var i = 0;i<this._datas.length;i++){
const ele = this._datas[i];
if(this.isEqual(ele.key,key)){
this._datas.splice(i,1);
}
}
}
clear(){
this._datas.length = 0;
}
*[Symbol.iterator](){
for(const item of this._datas){
yield [item.key,item.value]
}
}
}
# WeakSet && WeakMap
# WeakSet
与 set 基本完全相同
不同点:
- 内部存储的对象地址不会影响垃圾回收。即对象引用消失,WeakSet中的成员也会消失。
- 只能添加对象
- 不能遍历、没有 size 属性、
# WeakMap
与 map 基本完全相同
不同点:
- 键不会影响垃圾回收。
- 键必须是对象。