Set和Map数据结构
1.Set
(1)概述
es6提供的一种新的数据结构;类似数组,但元素都是唯一的,不重复
Set本身是一个构造函数,用来生成Set数据结构new Set()函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化;
因此,也可以使用该函数来实现数组去重:arr=[...new Set(arr)];
另一种方法:Array.from(new Set(arr)); (Array.from()可以将Set结构转换成数组)
注意点:
1)不会对数据进行类型转换,例如5和'5'是不同的;
加入元素时判断是否有重复,用的是'Same-value equality'算法,与===很相似,只是该算法认为NaN与NaN是相等的,而===认为是不相等的
;注意:两个对象始终是不相等的,即使是两个空对象,{}==={}//false
(2)Set实例的属性和方法
1)属性:
Set.prototype.constructor:构造函数,默认就是Set函数;
Set.prototype.size:返回Set实例的成员总数
2)操作方法:
add(value):添加某个值,返回 Set 结构本身。
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
has(value):返回一个布尔值,表示该值是否为Set的成员。
clear():清除所有成员,没有返回值。
3)遍历方法:
keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器
forEach():使用回调函数遍历每个成员
注:Set的遍历顺序就是插入顺序。这个特性有时非常有用,比如使用 Set 保存一个回调函数列表,调用时就能保证按照添加顺序调用
遍历的应用:
2.实现数组去重
3.在遍历操作中同步改变原来的set数据的方法:
2.WeakSet
与Set相似,有两个区别:
1)成员只能是对象
2)成员对象都是弱引用,即垃圾回收机制不考虑WeakSet对成员对象的引用,一旦成员对象不再被其他对象引用,就会被回收;由于垃圾回收机制,该数据结构是不可遍历的,没有size属性
3.Map
(1)含义和基本用法
类似于对象,但功能更强大,都是键值对的集合(hash结构);对象的键只能是字符串,而Map的键可以是各种类型的值(包括对象),是一种更完善的hash结构;
任何具有 Iterator 接口、且每个成员都是一个双元素的数组的数据结构(详见《Iterator》一章)都可以当作Map构造函数的参数
如果对同一个键多次赋值,后面的值将覆盖前面的值、
特别注意,只有对同一个对象的引用,Map结构才将其视为同一个键。
例子如下:
['a']===['a'] //false!!!改写成如下就可以获取:
确保键是对同一个对象的引用由此可知,Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。这就解决了同名属性碰撞(clash)的问题
如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键,比如0和-0就是一个键,布尔值true和字符串true则是两个不同的键。另外,undefined和null也是两个不同的键。虽然NaN不严格相等于自身,但 Map 将其视为同一个键(判断规则和===类似,只是对NaN的处理不同)
(2)实例的属性和操作方法
1)size属性:返回Map结构的成员总数
2)set(key,value):设置键及值,返回整个Map结构,因此可以采用链式写法:
set方法的链式写法3)get(key):获取键值,如果找不到key,则返回undefined
4)has(key):某键是否在Map对象中
5)delete(key):删除某个键,成功返回true,失败则返回false
6)clear():清除所有成员,没有返回值
(3)遍历方法
Map结构原生提供三个遍历器生成函数和一个遍历方法;
注意:Map结构中的遍历顺序就是成员插入的顺序,
而不是像对象那样有遍历顺序的规则(同下方的属性遍历的次序规则):
属性遍历的次序规则:
首先遍历所有数值键,按照数值升序排列。
其次遍历所有字符串键,按照加入时间升序排列。
最后遍历所有 Symbol 键,按照加入时间升序排列。
Map的默认遍历器接口就是entries方法keys():返回键名的遍历器。
values():返回键值的遍历器。
entries():返回所有成员的遍历器。
forEach():遍历 Map 的所有成员。
可以使用扩展运算符(...)较快速地将Map结构转成数组结构,之后就可以使用数组的map和filter方法,实现遍历和过滤
forEach()方法和数组的forEach()方法相似,最多可以接受2个参数,例子如下:
(4)与其他数据结构的互相转换
1)Map转换为数组:用扩展运算符,如:[...Map]
2)数组转换为Map: 使用构造函数new Map(array)
3)Map转换为对象:如果Map的所有key都是字符串,可以转换
4)对象转换成Map:for...of,以及set方法
5)Map转换成JSON
两种情况
key都是字符串时,map转成对象再用JOSN.stringify()方法即可
key不仅仅只是字符串时,map转成数组再用JSON.stringify()方法即可
6)JSON转换成Map
也分两种情况
1.键名都是字符串 2.整个 JSON 就是一个数组,且每个数组成员本身,又是一个有两个成员的数组4.WeakMap
与Map类似,两点区别:
区别1:只接受对象(除null外)作为键名
区别2:键名所指向的对象,不计入垃圾回收机制(键名是弱引用,键值仍是正常引用),内存泄漏的可能性比较小;因此,该数据结构没有遍历操作,也没有sizes属性;
只有4个方法:set(),get(),has(),delete()
用途:1)DOM节点作为键名
2)部署私有属性
网友评论