前言
很早之前向小伙伴们推荐了阮一峰老师的es6入门一书,结果,到头来,自己倒是忘了不少。正巧最近用到了Map,整理整理,方便后续自己查阅。
Map是es6提供的一种数据结构。
不得不说,Map的查找速度比其他常用的方法确实要强上不少。
属性和基本方法
1. size属性
返回Map结构的成员总数
const map = new Map();
map.set('name', 'hsl');
map.set('age', '20');
map.size; // 2
2. set(key, value)
set方法设置键值对,然后返回整个Map结构。
const map = new Map();
map.set('name', 'hsl');
map.set('age', '20');
在浏览器的控制台输出map,如下图:
注意,如果key已经有值,则键值会被更新。
const map = new Map();
map.set('name', 'hsl');
map.set('age', '20');
map.set('age', '22');
// 最后map里的age是22
Map结构里的key除了字符串,也可以用其他类型,比如:
const map = new Map();
map.set('name', 'hsl'); // key是字符串
map.set(0, 'hhh'); // key是数字
map.set(undefined, 'lalala'); // key是undefined
const fn = () => { console.log('hello');}
map.set(fn, 'hello world'); // key是函数
如果觉得一个一个的set麻烦的话,也可以采用链式写法。
const map = new Map()
.set(1, 'a')
.set(2, 'b')
.set(3, 'c');
// 上面的写法和下面是一样的哦
const map = new Map();
map.set(1, 'a')
map.set(2, 'b')
map.set(3, 'c');
3. get(key)
get方法读取key对应的键值,如果找不到key,返回undefined。
const map = new Map();
map.set('name', 'hsl')
map.get('name'); // a
4. has(key)
has方法返回一个布尔值,表示某个键是否在当前Map对象之中。
const map = new Map();
map.set('name', 'hsl');
map.has('name'); // true
map.has('age'); // false
5. delete(key)
delete方法删除某个键,返回true。如果删除失败,返回false。
const map = new Map();
map.set('name', 'hsl');
map.has('name'); // true
map.delete('name'); // true
map.has('name'); // false
map.delete('name'); // false
map.delete('age'); // false
6. clear()
clear方法清除所有成员,没有返回值。
const map = new Map();
map.set('name', 'hsl');
map.set('age', 20);
map.size; // 2
map.clear();
map.size; // 0
基本的使用方法介绍完了,来看一个小栗子(嘿嘿):
const a = [];
const b = [];
const map = new Map();
map.set(a, '向上');
map.set(b, '向下');
map.size; // ?
所以,size是多少呢?
前面我们有提到过,如果key值相同,后面的会覆盖前面的。正常来讲,size应该为1对吧?但这里不是,为什么呢?因为[] !== [](内存地址不同),所以size返回的是2。
这里,我们几乎可以得出一个结论:
如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键。
比如:
- 0和-0就是一个键
- 布尔值true和字符串true则是两个不同的键
- undefined和null也是两个不同的键
- NaN不严格相等于自身,但 Map 将其视为同一个键。
遍历方法
1. keys()
返回键名的遍历器
const map = new Map([
['name', 'hsl'],
['age', '20'],
]);
for (let key of map.keys()) {
console.log(key);
}
// name
// age
2. values()
返回键值的遍历器
const map = new Map([
['name', 'hsl'],
['age', '20'],
]);
for (let key of map.values()) {
console.log(key);
}
// hsl
// 20
3. entries()
返回所有成员的遍历器
const map = new Map([
['name', 'hsl'],
['age', '20'],
]);
for (let key of map.entries()) {
console.log(key);
}
// ["name", "hsl"]
// ["age", '20']
4. forEach()
遍历Map的所有成员
const map = new Map([
['name', 'hsl'],
['age', '20'],
]);
map.forEach(function(value, key, map) {
console.log(key, value);
});
// name hsl
// age 20
数据转换
1、Map转为数组
最简单的方法应该就是扩展运算符(...
)了。
const map = new Map()
.set('name', 'hsl')
.set('age', 20);
[...map];
// [["name","hsl"], ["age", 20]]
2、数组转为Map
直接传入Map构造函数即可。
new Map([
["name","hsl"],
["age", 20]
]);
// Map {
// "name" => "hsl",
// "age" => 20
// }
3、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);
strMapToObj(myMap)
// { yes: true, no: false}
4、对象转为 Map
(1)通过Object.entries()
let obj = { 'name': 'hsl', 'age': 20 };
// Object.entries(obj)是一个数组
let map = new Map(Object.entries(obj));
(2)转换函数
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
objToStrMap({yes: true, no: false})
// Map {"yes" => true, "no" => false}
5、Map转JSON
(1)Map 的键名都是字符串,可选择转为对象 JSON。
function strMapToJson(strMap) {
// 1、strMap转为对象obj:strMapToObj(strMap)
// 2、对象转为JSON:JSON.stringify(obj)
return JSON.stringify(strMapToObj(strMap));
}
let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap);
// '{"yes":true,"no":false}'
(2)Map 的键名有非字符串,可选择转为数组 JSON。
function mapToArrayJson(map) {
// 先转换成数组 [...map]
return JSON.stringify([...map]);
}
let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
mapToArrayJson(myMap);
// '[[true,7],[{"foo":3},["abc"]]]'
6、JSON转Map
(1)正常情况下,JSON 转为 Map,所有键名都是字符串。
function jsonToStrMap(jsonStr) {
return objToStrMap(JSON.parse(jsonStr));
}
jsonToStrMap('{"yes": true, "no": false}');
// Map {'yes' => true, 'no' => false}
(2)特殊情况下,整个 JSON 就是一个数组,且每个数组成员本身,又是一个有两个成员的数组。这时,它可以一一对应地转为 Map。这往往是 Map 转为数组 JSON 的逆操作。
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
jsonToMap('[[true,7],[{"foo":3},["abc"]]]');
// Map {true => 7, Object {foo: 3} => ['abc']}