今天我们来学习ES6中的另一个新数据类型Map
,和Set
数据结构不同,Map
主要来存储key-value结构数据,让我们来看看它和JS中的对象有何不同。
Map
简介
在没有ES6之前,我们要用到key-value数据结构时,经常会使用对象,因为对象可以将key对应的值设置成任何数据类型。
然而使用对象也有一些问题:
- JS中的对象都有prototype属性
- 对象的key必须是字符串或者symbol,不能使用对象作为key
- 对象没有表示对象长度的属性,像size或者length
ES6提供了新的数据类型Map
解决了这些问题。
Map
对象也是一种key-value的数据结构,任何类型的值都可以作为key或者value,另外Map
对象还会记住key的原始插入顺序,这点和Set
一样。
创建一个Map
对象
let map = new Map([iterable]);
Map
()可传入一个可迭代对象,其元素为key-value结构
一些常用 Map()
方法
clear()
– 清空Map中全部key-valuedelete(key)
– 删除Map中的指定key,如果key存在,返回该元素,如不存在返回false。entries()
– 返回一个可迭代对象,结构为数组[key, value]
,按照其插入顺序。forEach(callback[, thisArg])
– 循环Map中每个元素,按照插入顺序,可选thisArg设置回调函数中的this值。get(key)
– 返回和key关联的值,如不存在返回undefined。has(key)
– 如果key存在返回true,否则返回false。keys()
– 返回可迭代对象,其值为插入顺序时的key。set(key, value)
– 向Map中添加key-value数据,返回本身Map对象,可使用链式调用。values()
返回可迭代对象,其值为插入顺序时的value。
Map
使用示例
创建Map对象
假如我们有下面的一些汽车数据
let bmw = {brand: 'bmw'},
byd = {brand: 'byd'},
ford = {brand: 'ford'};
我们假设要把这些汽车和对应的国家做映射
let carsCountry = new Map();
carsCountry为我们创建的Map实例,它是object类型
console.log(typeof(carsCountry));
// 输出:object
console.log(carsCountry instanceof Map);
// 输出:true
添加数据到Map
中
使用set()方法向Map中添加数据
carsCountry.set(bmw, 'Germany');
使用set()方法将bmw对象映射到Germany,set方法会返回Map本身对象,所以也可以使用链式调用
carsCountry.set(byd, 'China')
.set(ford, 'America');
带有初始数据
我们可以在创建Map对象时,将初始数据传入Map构造函数中,数据格式为一个二维的数组
let carsCountry = new Map([
[bmw, 'Germany'],
[byd, 'China'],
[ford, 'America']
]);
从Map
中获取数据
从Map中获取数据也很简单,使用get()方法
carsCountry.get(bmw);
// 输出:Germany
如果数据不存在,会返回undefined
let foo = {name: 'Foo'};
carsCountry.get(foo);
// 输出:undefined
判断一个key是否存在
使用has方法判断key是否存在于Map对象中
carsCountry.has(foo);
// 输出:false
carsCountry.has(bmw);
// 输出:true
获取Map
中元素数量
使用size属性得到Map中的元素数量
console.log(carsCountry.size);
// 输出:3
迭代Map
中的key
使用keys()方法来获取Map中的所有key,keys()方法返回一个可迭代对象。
for (let car of carsCountry.keys()) {
console.log(car.brand);
}
// bmw
// byd
// ford
迭代Map
中的value
同样,使用values()方法可以获取Map中的所有值,同样返回一个可迭代对象。
for (let country of carsCountry.values()) {
console.log(country);
}
// Germany
// China
// America
迭代Map
元素
同样,使用 entries()
方法也会返回可迭代对象,每个元素为一个数据结构包含key-value,像这样[key,value]。
for (let elem of carsCountry.entries()) {
console.log(`${elem[0].brand}: ${elem[1]}`);
}
// bmw: Germany
// byd: China
// ford: America
为了使代码更加清晰明了,我们可以使用ES6的解构方法
for (let [car, country] of carsCountry.entries()) {
console.log(`${car.brand}: ${country}`);
}
除了使用for/of循环,Map对象同样提供了forEach方法
carsCountry.forEach((country, car) =>
console.log(`${car.brand}: ${country}`)
);
将Map
中的key转换数组
有时我们可能需要使用数组,而不是可迭代对象,这时我们可以使用ES6的展开运算符
var keys = [...carsCountry.keys()];
console.log(keys);
输出:
[{brand: 'bmw'},
{brand: 'byd'},
{brand: 'ford'}]
同样,也可以把value转换为数组
var countrys = [...carsCountry.values()];
console.log(countrys);
输出:
['Germany', 'China', 'America']
删除Map
中元素
使用delete()方法删除Map中的元素,传入对应的key,删除成功后会返回true
carsCountry.delete(bmw);
// true
清空Map
中全部元素
清空Map对象使用clear()方法
carsCountry.clear();
接着查看Map的长度,变为0
console.log(carsCountry.size);
// 0
WeakMap
WeakMap
类似于Map
,WeakMap
的key必须是对象,如果对象被GC垃圾回收,对应的值也会从内存中释放。
WeakMap
只有 Map
的几个子集方法:
get(key)
set(key, value)
has(key)
delete(key)
下面是Map和
WeekMap`的主要区别:
- WeakMap 不能被迭代
- WeakMap 不能被clear一次性清空掉
- WeakMap 不能使用size查看长度
今天我们主要学习了Map的使用,和一些简单的示例,以及和WeakMap的主要区别。
如果文章有帮助,微信搜索【小帅的编程笔记】,让我们每天进步