ES6新对象Set和Map来了,其他对象请鼓掌欢迎👏
为什么要新添加这两种数据结构
Set
用来解决集合中每个值只能有唯一的值,所以set中在添加的值的时候涉及值相等判断,-0
,+0
应被当作不同的值对待,但在最新的 ECMAScript 6规范中这点已被更改,所以Set中-0
,+0
都是0
;虽然NaN!=NaN
,但在set中也只能被添加一次。
Map
和对象有以下几点不同
- 对象有
prototype
,如果给对象实例上添加了和原型上一样的属性值,则访问不到原型上的那个值了 - 对象的键可以是字符串和
Symbols
,Map
的键可以是任意类型,包括函数,对象或者其他原始类型 - 可以轻易的通过
Map
的size
属性来获得Map
的大小,要获得对象的大小需要手动编码计数获得
Map
和Set
在新建时都可直接传入可迭代对象,而传入Map中对象的元素必须是键值对的形式。set实例对象和map实例对象都是可迭代对象,通过for...of
遍历时,因为es6在设计这两种结构的时候,添加会保存顺序,所以会按添加的顺序遍历出来,相比对象字面量和数组字面量,Map和Set实例提供了更多的方法
Set
set,在数学概念中称为”集合”。集合在我们上初中时候就已经学过,著名的三大特性为确定性,互异性,无序性。es6中的set也刚好有这三种特性,并且也可以轻松实现集合中的交集,并集,差集。
属性和方法
静态属性
- Set.length:值为0
原型属性
- set.size:返回set对象中值的个数
原型方法
- set.add(value):添加指定的值,若重复则不添加,返回set实例对象
- set.has(value):判断是否有指定的值,返回boolean值
- set.delete(value):删除指定的值,返回boolean值
- set.clear():删除所有的值
- set.keys()/set.values()/
set[@@iterator]()
:将set对象中每个元素的值按插入序取出来作为新的迭代器对象的值并返回 - set.entries():将set对象中每个元素按插入序取出来组合成[value,value]数组的形式作为新的迭代器对象的值并返回
set.forEach(cb[, thisArg])
:cb函数中对set对象中的每个值按插入序进行操作,如果传入第二个参数,将作为cb函数中this的值
应用
实现数组的去重
|
|
并集的实现
|
|
交集的实现
|
|
差集的实现
|
|
根据上述的例子,我们也看到了Set和Array之间是如何互相转化,利用各自的方法和属性可以巧妙而简洁的写出想要的功能
Map
属性和方法
静态属性
- Map.length:值为0
原型属性
- map.size:map实例对象上键值对的个数
原型方法
- map.get(key):如果能找到的话,返回key对应的value,否则返回undefined
- map.set(key, value):为map实例添加指定的key-value对,返回map实例对象
- map.has(key):根据指定的key查找是否有关联的value,返回boolean值
- map.delete(key):根据指定的key查找是否有关联的value,有的话删除并返回true,没有的话返回false
- map.clear():清空map实例对象的所有key-value对
- map.keys():将map对象的每个元素中的key按插入序取出来作为新的迭代器对象的值并返回
- map.values():将map对象的每个元素中的value按插入序取出来作为新的迭代器对象的值并返回
- map.entries()/
map[@@iterator]()
:将map对象中每个元素按插入序取出来组合成[key,value]数组的形式作为新的迭代器对象的值并返回 map.forEach(cb[, thisArg])
:与set方法的forEach使用一样
注意点
set添加值
基本类型
添加基本类型值的时候,如果set
方法传入的key
相等,会覆盖掉上次的值,这里也同样涉及到值相等的判断,对于基本类型值,只要两个值严格相等,Map
将其视为一个键,undefined
和null
也是两个不同的键。
引用类型
添加引用类型值的时候,Map的键根据内存地址来判断是否是相等的值,也就是说即使传入了两个空对象,但是这两个对象分配的地址不同,也会被Map添加两次,如果我们使用Map,以对象作为键名,可以避免与其他人的命名冲突(思考:对象中为防止命名冲突,新增了 Symbol 类型,那 Symbol 能用于 Map 对象中的键吗?)