小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
本文同时参与「掘力星计划」,赢取创作大礼包,挑战创作激励金
前言
小伙伴们大家好,前面我们已经学习了es6中的Set和WeakSet两种数据结构,今天将给大家分享es6为我们提供的另一种数据结构Map。
大家都知道在JavaScript的对象(Object)中,只能用字符串类型作为对象的key,即使我们在写的时候用了其它类型的key,那么Object也会自动把它转换为字符串类型。但有时候由于业务需要,我们想用一些其它类型来作为对象的key,比如说dom对象,这个时候Object显然已经无法满足我们的需求了,因为dom对象最终会被转换为字符串类型[object HTMLDivElement]。为了解决这个问题,ES6 为我们提供了 Map 数据结构。下面我们来具体分析。
Map
ES6中的Map数据结构类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构则提供了“值—值”的对应,是一种更完善的 Hash 结构实现。Map数据结构有如下一些特点:
- Map是键值对的集合,键值不限于字符串,可以是任意数据类型
- Map通过set方法添加成,通过get方法来获取成员
- Map也是构造函数,也可以接受一个数组作为参数,但该数组的成员也必须是一个个表示键值对的数组。例如:[["name","Alvin"],["age",18]]
- 不仅仅是数组,任何具有 Iterator 接口、且每个成员都是一个双元素的数组的数据结构都可以当作Map构造函数的参数。包括Set和Map本身。
- 如果对同一个键多次赋值,后面的值将覆盖前面的值
- 如果读取一个不存在的键则返回undefined
- 只有对同一对象的引用,Map才会视为同一个键。也就是说两个对象的内存地址是一样的,才会被视为是同一个键。(Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键)
- 如果Map的键值是一个基本类型(数字,字符串,布尔等),则只要两个值严格相等(类型和值都相等)才算是同一个键,如0和-0就是同一键,而true和"true"则是两个键
- undefined 和 null是两个不同的键
- NaN在Map中被视为同一个键
下面我们来看一些小案例
//1. 任意类型作为键名
//2. 通过set添加成员,get访问成员
const m = new Map();
const o = {"p": 'Hello World'};
m.set(o, 'content')
m.get(o) // "content"
//3. 数组作为构造函数的参数,且数组的成员必须也是包含了一个个表示键值对的数组
const map = new Map([
['name', 'Alvin'],
['age', 18]
]);
map.get("name");//"Alvin"
map.get('age') // 18
//4. Set和Map对象作为Map构造函数的参数
const set = new Set([
['chj', 1],
['cyq', 2]
]);
const m1 = new Map(set);
m1.get('chj') // 1
const m2 = new Map([['lqy', 3]]);
const m3 = new Map(m2);
m3.get('lqy') // 3
//5. 对同一个键多次赋值
//6. 读取一个不存在的键
const map = new Map();
map
.set('chj', 'aaa')
.set('chj', 'bbb');
map.get('chj') // "bbb"
map.get('clyq') // undefined
//7. 不同地址的相同值的对象作为键
map.set(['lyq'],'lyq')
map.set(['lyq'],'shn')
map.get(['lyq']);//undefined
const lyq = ['lyq']
const xhj = ['lyq']
map.set(lyq,'lyq').set(xhj,'xhj')
map.get(lyq);//'lyq'
map.get(xhj);//'xhj'
//8. undefined和null作为键
//9. NaN作为键
//10. 0和-0,true和"true"作为键
let map = new Map();
map.set(undefined, 3);
map.set(null, 4);
map.get(undefined) // 3
map.set(NaN, 123);
map.set(NaN, 234);
map.get(NaN) // 234
map.set(-0, 123);
map.get(+0) // 123
map.set(true, 1);
map.set('true', 2);
map.get(true) // 1
Map 的实例属性和方法
为了方便对Map的操作,同样为我们提供了一套实例属性和方法,细心的小伙伴应该已经发现,其实在上面的案例中我们已经用过了两个方法了,下面我们来看一下每个方法的作用和用法
- set(key, value)方法用于设置Map的键和值,返回值为整个Map结构,因此set方法也是可以连用的。另外如果key已经存在则更新原值,否则添加新值。
- get(key),Map通过get方法并传入key作为参数来获取对应的值,如果key不存在返回undefined
- has(key)方法用于判断key在Map中是否存在,返回值为布尔类型,存在返回true否则返回false
- delete(key)方法用于删除Map中的key,返回值为布尔类型,用于标识是否删除成功
- clear()方法没有参数也没用返回值,用于清空Map中所有的成员
- size,size是实例的一个属性,用于标识当前Map中一共有多少个成员,返回值是一个数字
- keys()方法用于遍历Map数据结构,返回Map中的所有的键
- values()方法用于遍历Map数据结构,返回Map中所有的值
- entries()方法用于遍历Map数据结构,返回Map中多有的键值对
- forEach()方法与数组的用法一样,遍历Map中所有的成员,可以根据业务需要进行一些操作
关于简单的操作方法这里不再演示了,下面简单演示一下几个遍历函数的一些用法
const map = new Map([['hj','xhj'],['yq','lyq'],['hn','xhn'],['yl','yyl']])
for (let key of map.keys()) {
console.log(key);// 'hj' 'yq' 'hn' 'yl'
}
for (let value of map.values()) {
console.log(value);// 'xhj' 'lyq' 'xhn' 'yyl'
}
for (let item of map.entries()) {
console.log(item[0], item[1]);
}
// "hj" "xhj"
// "yq" "lyq"
// "hn" "xhn"
// "yl" "yyl"
// 或者
for (let [key, value] of map.entries()) {
console.log(key, value);
}
// "hj" "xhj"
// "yq" "lyq"
// "hn" "xhn"
// "yl" "yyl"
// 等同于使用map.entries()
for (let [key, value] of map) {
console.log(key, value);
}
总结
本文我们有学习了一个新的数据结构Map,发现Map比前面学过的Set和WeakSet还要强大,既像对象又像集合,但同时又比对象和集合功能更强大。本篇文章就先介绍到这里,下一篇内容中将给大家分享一下关于Map转换为其它类型和WeakMap的相关知识。
喜欢的小伙伴欢迎点赞留言加关注哦!