ES6新特性总结Set集合Map集合
Posted 橘猫吃不胖~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6新特性总结Set集合Map集合相关的知识,希望对你有一定的参考价值。
ES6新特性(3)Set集合、Map集合
1 Set集合
Set集合:是一种数据结构,结构类似于数组,且没有重复的值。主要用于数组去重,字符串去重。
1.1 操作方法
方法 | 含义 |
---|---|
add() | 添加值,返回Set结构本身 |
delete() | 删除值,返回一个boolean表示是否删除成功 |
has() | 判断该值是否存在,并返回一个boolean |
clear() | 清除所有值,没有返回值 |
add()使用示例:
let s = new Set();
s.add(1); //添加一个值1
console.log(s); //返回s结构本身
结果为:Set(1) 1
let s = new Set();
s.add(1).add(2).add(1); //连续添加三次数,其中1重复添加
console.log(s); //输出Set结构本身
结果为:Set(2) 1, 2
上面的代码中添加了两次1,但是s中只有一个1,因此Set中没有重复的值。根据观察,前两次的结果前面都加了“Set”,而有时候 中才是我们想要的结果,因此我们可以使用拓展运算符(…)将Set的值扩展出来。
let s = new Set();
s.add(1).add(2).add(1); //为s添加3次数字
console.log(...s) //将Set的值扩展出来
输出结果为:1 2
输出结果是一个序列,我们可以通过加一个[ ]来将其变成数组。
let s = new Set();
s.add(1).add(2).add(1); //为s添加3次数字
console.log([...s]) //输出为数组
输出结果为:[ 1, 2 ]
delete()使用示例:
let s = new Set();
s.add(1).add(2); //为Set添加了两个数:1和2
console.log("删除前:", ...s); //输出1 2
s.delete(1); //将1删除掉
console.log("删除后:", ...s); //输出2
输出结果为:
删除前: 1 2
删除后: 2
delete()返回值是判断该数有没有删除成功,因此上一段代码中,s.delete(1)的返回值一定是true。
let s = new Set();
s.add(1).add(2); //为Set添加了两个数:1和2
console.log(s.delete(1)); //输出删除1后的返回值
输出结果为:true
如果删除一个s中不存在的数,那么它的返回值就是false。
let s = new Set();
s.add(1).add(2); //为Set添加了两个数:1和2
console.log(s.delete(3)); //输出删除3后的返回值
console.log(...s); //输出s
结果为:
false
1 2
从上面的结果可以看出,如果删除一个不存在的数,它的返回值是false,但是对原来的Set集合结果并不影响,程序不会报错,会正常输出原来的Set集合。
has()使用示例:
let s = new Set();
s.add(1).add(2); //为s添加两个数1和2
console.log(s.has(1)); //判断s中含不含1
console.log(s.has(3)); //判断s中含不含3
结果为:true false
如果该值存在于Set集合中,那么返回值为true;如果该值不存在于Set集合中,那么返回值为false。
clear()使用示例:
let s = new Set();
s.add(1).add(2); //为s添加两个数1和2
s.clear(); //清除所有的值
console.log(s);
输出结果为:Set(0)
1.2 遍历方法
由于Set只有键值没有键名,也可以说键和值是同一个(键、值相同,可以省略) ,所keys和values返回值相同。
let set = new Set();
set.add(1).add(2).add(3); //添加3个数:1,2,3
for (let i of set.keys()) //遍历set集合的键,keys()代表键
console.log(i); //输出set集合的键
输出结果为:1 2 3
let set = new Set();
set.add(1).add(2).add(3); //添加3个数:1,2,3
for (let i of set.values()) //遍历set集合的键,keys()代表键
console.log(i); //输出set集合的键
输出结果为:1 2 3
let set = new Set();
set.add("hello").add("world"); //添加两个字符串
for (let i of set.entries()) //遍历set的键值对,entries()代表键值对
console.log(i); //输出遍历的结果
输出结果为:
[ ‘hello’, ‘hello’ ]
[ ‘world’, ‘world’ ]
使用forEach()遍历Set集合。
let set = new Set();
set.add("hello").add("world"); //为set添加两个字符串
set.forEach((key, val) => //遍历键和值
console.log(key + "||" + val); //输出键和值
)
输出结果为:
hello||hello
world||world
Set可以接受一个数组作为参数。
let arr = ["小红", "小明", "小强", "小明"];
let set = new Set(arr); //将arr数组作为参数传给set集合
console.log(...set); //输出set集合
结果为:小红 小明 小强
【案例】Set实现并集与交集。
let arr1 = [4, 5, 6];
let arr2 = [5, 6, 7];
let setA = new Set(arr1);
let setB = new Set(arr2);
//求并集,将两个集合合并在一起,去掉多余的重复的数字
let bingji = new Set([...setA, ...setB]);
console.log(...bingji); //输出并集的结果
//求交集,将两个集合合并在一起,求重复的数字,使用filter过滤器得到结果
//在setA中过滤出与setB共同含有的值
let jiaoji = new Set([...setA].filter(val => setB.has(val)));
console.log(...jiaoji); //输出交集的结果
结果为:
4 5 6 7
5 6
1.3 WeakSet
WeakSet只能是对象的集合,而不能是任何类型的任意值。
WeakSet集合中对象的引用为弱引用。如果没有其他的对WeakSet中对象的引用,那么这些对象会被当成垃圾回收掉。
这也意味着WeakSet中没有存储当前对象的列表。正因为这样,WeakSet 是不可枚举的。即WeakSet中对对象的引用不会被考虑进垃圾回收机制,即只要没有其他的对象引用该对象,则该对象就会被回收,而不管它在不在 WeakSet。
WeakSet 支持 add,has 和 delete 方法,但不支持 size 和 keys(),并且不可迭代,无法遍历。
为weakSet添加对象,查看其返回值:
let jack = name: "jack" ; //jack是一个对象
let weakSet = new WeakSet();
weakSet.add(jack); //为weakSet添加一个对象
console.log(weakSet.has(jack)); //判断weakSet是否含有jack,并输出返回值
得到结果为:true
删除刚刚添加的对象,查看返回值:
let jack = name: "jack" ; //jack是一个对象
let weakSet = new WeakSet();
weakSet.add(jack); //为weakSet添加一个对象
weakSet.delete(jack); //将jack从weakSet中删除掉
console.log(weakSet.has(jack)); //判断weakSet是否含有jack,并输出返回值
得到结果:false
为WeakSet添加除了对象之外的内容,查看其结果:
let jack = name: "jack" ; //jack是一个对象
let weakSet = new WeakSet();
weakSet.add(1); //为weakSet添加除对象之外的值
程序会报错:TypeError: Invalid value used in weak set,因为WeakSet中只能存放对象。
WeakSet 的应用场景/好处:用于存储DOM节点,而不用担心这些节点从文档移除时会引发内存泄露。
2 Map集合
2.1 Map概述
javascript的对象(Object),本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。
为了解决这个问题,ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object结构提供了“字符串——值”的对应,Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现。
ES6中的Map类型是一种储存着许多键值对的有序列表,其中的键名和对应的值支持所有的数据类型。键名的等价性判断是通过调用Object.is()
方法实现的,所以数字5与字符串"5"会被判定为两种类型,可以分别作为独立的两个键出现在程序中,这一点与对象不一样,因为对象的属性名总会被强制转换成字符串类型。
注意:
1、有一个例外,Map集合中将+0和-0视为相等,与Object.is()结果不同。
2、如果需要“键值对”的数据结构,Map比Object更合适,具有极快的查找速度
2.2 基本方法和属性
1、属性:size,返回Map中的元素个数
2、基本方法
方法 | 含义 |
---|---|
set() | 给Map添加数据,返回添加后的Map (给已存在的键赋值会覆盖掉之前的值) |
get() | 获取某个key的值,返回key对应的值,没有则返回undefined |
has() | 检测是否存在某个key,返回布尔值 |
delete() | 删除某个key及其对应的value,返回布尔值,成功:true; 失败:false |
clear() | 清除所有的值,返回 undefined |
size、set()使用示例:
let map = new Map();
map.set("name", "橘猫吃不胖"); //为map添加数据
map.set("age", 2); //为map添加数据
console.log(map.size); //输出map中元素个数(长度)
console.log(map); //输出添加数据后的map
输出结果为:
2
Map(2) ‘name’ => ‘橘猫吃不胖’, ‘age’ => 2
get()使用示例:
let map = new Map();
map.set("name", "橘猫吃不胖"); //为map添加数据
map.set("age", 2); //为map添加数据
console.log(map.get("name")); //输出name对应的值
console.log(map.get("address")); //当没有该键时返回undefined
输出结果为:
橘猫吃不胖
undefined
has()使用示例:
let map = new Map();
map.set("name", "橘猫吃不胖"); //为map添加数据
map.set("age", 2); //为map添加数据
console.log(map.has("name")); //判断map中是否含有name
console.log(map.has("address")); //判断map中是否含有address
输出结果为:
true
false
delete()使用示例:
let map = new Map();
map.set("name", "橘猫吃不胖"); //为map添加数据
map.set("age", 2); //为map添加数据
console.log(map.delete("name")); //删除map中的name
console.log(map.delete("address")); //删除map中的address
输出结果为:
true
false
clear()使用示例:
let map = new Map();
map.set("name", "橘猫吃不胖"); //为map添加数据
map.set("age", 2); //为map添加数据
console.log(map); //输出添加值之后的map
console.log(map.clear()); //输出清除所有值之后的返回值
console.log(map); //输出清除值之后的map
输出结果为:
Map(2) ‘name’ => ‘橘猫吃不胖’, ‘age’ => 2
undefined
Map(0)
2.3 遍历方法
注意:Map的遍历顺序就是插入顺序
方法 | 含义 |
---|---|
keys() | 获取Map的所有key |
values() | 获取Map的所有值 |
entries() | 获取Map所有成员 |
forEach() | 遍历Map的所有成员 |
//创建一个map集合,传入一个二维数组
const map = new Map([
["F", "no"],
["T", "yes"]
])
console.log(map);
输出结果为:Map(2) ‘F’ => ‘no’, ‘T’ => ‘yes’
keys()使用示例:
//创建一个map集合,传入一个二维数组
const map = new Map([
["F", "no"],
["T", "yes"]
])
for (let key of map.keys()) //遍历map的键
console.log(key); //输出map的键
输出结果为:F T
values()使用示例:
//创建一个map集合,传入一个二维数组
const map = new Map([
["F", "no"],
["T", "yes"]
])
for (let value of map.values()) //遍历map的值
console.log(value); //输出map的值
输出结果为:
no
yes
entries()使用示例:
//创建一个map集合,传入一个二维数组
const map = new Map([
["F", "no"],
["T", "yes"]
])
for (let item of map.entries()) //遍历map所有成员
console.log(item); //输出map所有成员
输出结果为:
[ ‘F’, ‘no’ ]
[ ‘T’, ‘yes’ ]
或者:
//创建一个map集合,传入一个二维数组
const map = new Map([
["F", "no"],
["T", "yes"]
])
for (let [key, value] of map.entries()) //遍历map成员
console.log(key, value); //输出map成员
输出结果为:
F no
T yes
或者:
const map = new Map([
["F", "no"],
["T", "yes"]
])
// 等同于使用map.entries()
for (let [key, value] of map) //遍历map成员
console.log(key, value); //输出map成员
输出结果为:
F no
T yes
2.4 转为数组
Map结构转为数组结构,比较快速的方法是使用扩展运算符(…)。
//创建一个map集合
const map = new Map([
[1, "one"],
[2, "two"],
[3, "three"]
])
//将map的键转化为一个数组
console.log(...map.keys()); //1 2 3
//将map的值转化成一个数组
console.log(...map.values()); //one two three
//将map对象转化成一个数组
console.log(...map.entries()); //[ 1, 'one' ] [ 2, 'two' ] [ 3, 'three' ]
//将map转化成一个数组
console.log(...map); //[ 1, 'one' ] [ 2, 'two' ] [ 3, 'three' ]
2.5 Map的遍历和过滤
结合数组的map方法、filter方法,可以实现Map的遍历和过滤。
const map0 = new Map();
map0.set(1, "a"); //为map0添加数据
map0.set(2, "b"); //为map0添加数据
map0.set(3, "c"); //为map0添加数据
//filter()的使用
const map1 = new Map(
//将map0中键小于3的过滤出来
[...map0].filter(([k, v]) => k < 3)
);
console.log(map1); //Map(2) 1 => 'a', 2 => 'b'
//map()的使用
const map2 = new以上是关于ES6新特性总结Set集合Map集合的主要内容,如果未能解决你的问题,请参考以下文章
web前端练习17----es6新语法4,数组,Set集合,Map集合
ES6的新特性(14)——Iterator 和 for...of 循环