ES6新特性总结Set集合Map集合

Posted 橘猫吃不胖~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6新特性总结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集合的主要内容,如果未能解决你的问题,请参考以下文章

ES6新特性:Set和Map

ES6新语法(Set集合Map集合)

web前端练习17----es6新语法4,数组,Set集合,Map集合

ES6的新特性(14)——Iterator 和 for...of 循环

泛型,JDK5新特性,List集合子实现类,Map集合,Set/TreeSet集合,asList

ES6 7 8 9 10新特性总结