文章目录
前言
此系列文章用于记录小萌新的ES6的学习经历如有什么错误或者不好的地方请各位大佬多多指教
一、Set
1.1.Set概述
在Javascript中只有一个数组来表示集合数据,但是缺乏很多多表示的集合结构,如Python语言分为元组,列表,集合,字典
,每一种都有不同集合的特点,在ES6中Javascript也对自己的集合类型进行了扩展添加了集合Set
和字典Map
。
1.2.Set的基本用法
- Set的使用方法类似与数组,但是集合中不能存在相同的元素。
- 再创建的时候使用new关键字直接对Set构造方法进行实例构造即可。
代码如下(示例):
{
const s = new Set();
[2, 3, 4, 5, 2, 2].forEach(x => s.add(x));
for (let i of s) {
console.log(i); // 2 3 4 5
}
let set = new Set([1, 2, 3, 4, 4]);
console.log([...set]); //[ 1, 2, 3, 4 ]
}
Set构造函数可以接受一个数组(或具有Iterable接口的其他数据结构)作为参数,来初始化Set实例。
使用Set进行数组和字符串的去重操作
代码如下(示例):
{
let items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
console.log(...items); //1 2 3 4 5
let str = "abbcddef";
console.log([...new Set(str)].join("")); //abcdef
}
利用Set不能有重复元素的特点可以对具有迭代器的类型数据元素进行去重操作。(非常方便哦)
使用集合需要注意的地方
在于如果需要在集合中放入对象,他们并不会去重,因为在集合中各个元素进行比较的时候会使用内部比较机制
- 向Set实例加入值时不会发生类型转换,因此5和’5’是不同的。
- 利用算法“Same-value equality”来判断加入的值和已有的值是否相等,类似于Object.is( )方法,如果相等则不加入。
两个对象总是不相等的(因为他们比较的是对象的引用)
。
代码如下(示例):
{
let set = new Set();
set.add({});
set.add({});
console.log(set.size); //2
console.log(set); //Set(2) { {}, {} }
let a = {};
let b = a;
set.add(a);
set.add(b);
console.log(set.size); //3
console.log(set); //Set(3) { {}, {}, {} }
}
1.3.Set的属性与方法
属性
- constructor,构造函数,默认就是Set函数。
- size,返回Set实例的成员数量。(类似于数组的length)
操作方法
add(value)
,添加值,返回该Set实例的引用。delete(value)
,删除值,返回一个布尔值,表示删除是否成功。has(value)
,返回一个布尔值,表示该值是否是Set实例的成员。clear( )
,清除所有成员,没有返回值。
代码如下(示例):
{
let set = new Set();
set.add(1).add(2).add(2);
console.log(set); //Set(2) { 1, 2 }
console.log(set.has(2)); //true
console.log(set.has(3)); //false
set.delete(1);
console.log(set); //Set(1) { 2 }
set.clear();
console.log(set); //Set(0) {}
}
遍历方法
keys( )
,返回键名的遍历器。values( )
,返回键值的遍历器。entries( )
,返回键值对的遍历器。forEach( )
,使用回调函数遍历每个成员,没有返回值。
代码如下(示例):
{
let set = new Set(["red", "green", "blue"]);
for (let item of set.keys()) {
console.log(item); //red green blue
}
for (let item of set.values()) {
console.log(item); //red green blue
}
//Set结构实例的默认遍历器生成函数就是values()方法
for (let item of set) {
console.log(item); //red green blue
}
for (let item of set.entries()) {
console.log(item); //[ 'red', 'red' ] [ 'green', 'green' ] [ 'blue', 'blue' ]
}
set.forEach(value => console.log(value.toUpperCase()));
set.forEach((value, key, s) => {
console.log(s.size); //3 3 3
console.log(value); //red green blue
});
}
需要注意的是
因为Set集合没有键,所以对于集合来说键(key)
和值(value)
是一个东西。
1.4.Set的其他使用方法
Set集合可以先暂时转化成数组来借用数组的map()
和filter()
方法。
代码如下(示例):
{
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
//并集
let union = new Set([...a], [...b]);
console.log(union); //Set(3) { 1, 2, 3 }
//交集
let interect = new Set([...a].filter(x => b.has(x)));
console.log(interect); //Set(2) { 2, 3 }
//差集
let diffs = new Set([...a].filter(x => !b.has(x)));
console.log(diffs); //Set(1) { 1 }
}
二、Map
2.1.Map概述
Map类型是键值对的有序列表,而键和值都可以是任意类型。类似于Python的字典。
2.2.Map的基本用法
Map构造函数可以接收一个数组作为参数。
- 该数组的成员是一组表示键值对的数组。
- 不仅是数组,任何具有 Iterator 接口、且每个成员都是一个双元素的数组的数据结构都可以作为Map构造函数的参数。
- Set和Map都可以用来生成新的 Map。
并且Map和Set的操作方法基本一致(除了添加一个元素和获取一个元素):
set(key, value)
,设置(添加)键值对。get(key)
,通过key获取对应值。
类似Set的方法和属性
has(key)
delete(key)
clear( )
size
代码如下(示例):
{
let map = new Map([
['name', 'zhang'],
['title', 'Author']
]);
console.log(map.size); //2
console.log(map.has('name')); //true
console.log(map.get('name')); //zhang
console.log(map.has('title')); //true
console.log(map.get('title')); //Author
let o = { p: 'Hello world' };
map.set(o, 'content');
console.log(map.size); //3
console.log(map.get(o)); //content
console.log(map.has(o)); //true
console.log(map.delete(o)); //true
console.log(map.has(o)); //false
console.log(map.clear()); //undefined
console.log(map); //Map(0) {}
}
需要注意的是:
如果Map的键是一个简单类型的值(数值,字符串,布尔值)
,只要两个值严格相等
,Map就认为是同一个键
。并且如果Map的键是一个对象如果这两个对象的引用是一样
的则Map会把他们两个理解为同一个键
。
代码如下(示例):
{
const mm = new Map();
mm.set(["a"], 5);
console.log(mm.get(["a"])); //undefined
const k1 = {};
const k2 = {};
mm.set(k1, 100);
mm.set(k2, 200);
console.log(mm.get(k1), mm.get(k2)); //100 200
mm.set(-0, 123);
console.log(mm.get(+0)); //123
mm.set(true, 1);
mm.set("true", 2);
console.log(mm.get(true)); //1
console.log(mm.get("true")); //2
mm.set(undefined, 3);
mm.set(null, 4);
console.log(mm.get(undefined)); //3
console.log(mm.get(null)); //4
mm.set(NaN, 111);
console.log(mm.get(NaN)); //111
console.log(mm);
/*
Map(9) {
[ 'a' ] => 5,
{} => 100,
{} => 200,
0 => 123,
true => 1,
'true' => 2,
undefined => 3,
null => 4,
NaN => 111
}
*/
}
2.3.Map的遍历方法
- keys():返回键名的遍历器。
- values():返回键值的遍历器。
- entries():返回所有成员的遍历器。
- forEach():遍历 Map 的所有成员。
- Map 结构的默认遍历器接口(Symbol.iterator属性),就是entries方法。
代码如下(示例):
{
const map = new Map([
["F", "no"],
["T", "yes"]
]);
for (let [key, value] of map.entries()) {
console.log(key, value); //F no T yes
}
for (let [key, value] of map) {
console.log(key, value); //F no T yes
}
}
和Set一样可以把Map暂时转换成数组来借用数组的map()和filter()方法。
2.4.Map与其他类型集合的转换的方法
代码如下(示例):
{
//Map转换为数组
const myMap = new Map().set(true, 7).set({ foo: 3 }, ["abc"]);
let myArr = [...myMap];
console.log(myArr);
}
{
//数组转换为Map
const myMap = new Map([
[true, 7],
[{ foo: 3 }, ["abc"]]
]);
console.log(myMap);
}
{
//Map转换为对象
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k, v] of strMap) {
obj[k] = v;
}
return obj;
}
const myMap = new Map().set("yes", true).set("no", false);
let obj = strMapToObj(myMap);
console.log(obj, obj.yes, obj.no);
}
{
//对象转换成Map
function objToStrMap(obj) {
let strMap = new Map();
for (let [k, v] of Object.entries(obj)) {
strMap.set(k, v);
}
return strMap;
}
let myMap = objToStrMap({ yes: true, no: false });
console.log(myMap, myMap.get("yes"), myMap.get("no"));
}
{
//Map转换成Json
function strMapToJSON(strMap) {
//先将Map转换为对象,在通过对象生成JSON。
return JSON.stringify(strMapToObj(strMap));
}
let myMap = new Map().set("yes", true).set("no", false);
let json1 = strMapToJSON(myMap);
console.log(json1);
}
{
//Json转Map
function jsonToStrMap(jsonStr) {
return objToStrMap(JSON.parse(jsonStr));
}
let theMap = jsonToStrMap('{"yes":true, "no": false}');
console.log(theMap);
}
总结
本文主要讲述了ES6中的Set和Map方面的知识,如果又不好的地方希望大家多多提意见。