前言
- 在ES6之前,想实现键值对的存储,只能用Object来完成.
- ES6时引入Map,专门完成键值对的存储.
- Map其实和后端的关联数组,真的很像.
- 很多时候Map和Object是可以互相通用的,具体使用哪个,还得慢慢甄别.
一、基本用法
1 初始化
- 设置空的映射
let myMap = new Map();
- 初始化时,传入可迭代对象
const m1 = new Map([
['name', '小甜甜'],
['age', 18],
['info', '真的很甜']
]);
console.log(m1);
/* 打印结果
Map(3)
[[Entries]]
0: {"name" => "小甜甜"}
1: {"age" => 18}
2: {"info" => "真的很甜"}
size: 3
[[Prototype]]: Map
*/
2 val的操作
- set(key,val) 设置
const m1 = new Map();
m1.set('name', '牛夫人')
m1.set('hobby', '吃鸡');
console.log(m1);
// Map(2) {'name' => '牛夫人', 'hobby' => '吃鸡'}
由于set() 方法映射的实例,此处我们也可以连续调用.
const m1 = new Map();
// 设置
m1.set('name', '牛夫人').set('hobby', '吃鸡').set('age', 22);
console.log(m1); // Map(3) {'name' => '牛夫人', 'hobby' => '吃鸡', 'age' => 22}
- get(key) 获取值
const m1 = new Map();
// 设置
m1.set('name', '牛夫人')
m1.set('hobby', '吃鸡');
// 获取
console.log(m1.get('name')); // 牛夫人
// 获取不存在的key
console.log(m1.get('age')); // undefined
- has(key) 判断值是否存在
const m1 = new Map();
// 设置
m1.set('name', '牛夫人')
m1.set('hobby', '吃鸡');
// 存在
console.log(m1.has('age')); // false
// 不存在
console.log(m1.has('name')); // true
- size 返回当前key的个数,即map长度
const m1 = new Map();
// 设置
m1.set('name', '牛夫人')
m1.set('hobby', '吃鸡');
console.log(m1.size); // 2
3 键的类型
Map中的键可以是任何类型,值也Object一样没有任何限制.
const m = new Map();
const functionKey = function () { };
const objectKey = {};
const symbolKey = Symbol();
m.set(functionKey, '函数做为键');
m.set(objectKey, '对象作为键');
m.set(symbolKey, 'symbol作为键');
console.log(m);
二、顺序和迭代
1.for-of的使用
- map实例会保存插入的顺序,因此可以根据插入顺序进行迭代操作.
- 可以使用entries() 来实现这个迭代器,以数组形式返回[key,val].
const m = new Map([
['name', '小甜甜'],
['age', 22],
['info', '甜的血糖高']
]);
for (let pair of m.entries()) {
console.log(pair);
}
效果如下:
- 不使用迭代器,也可以用forEach() 回调函数的方式.
const m = new Map([
['name', '小甜甜'],
['age', 22],
['info', '甜的血糖高']
]);
m.forEach((val, key) => {
console.log(key, val);
})
效果如下
- keys() 和 values() 分别按照插入顺序返回key和val
const m = new Map([
['name', '小甜甜'],
['age', 22],
['info', '甜的血糖高']
]);
for (let key of m.keys()) {
console.log('key', key);
}
for (let val of m.values()) {
console.log('values', val);
}
三、Objects 和 maps 的差异
- 键的对比
Map 默认情况不包含任何键,只包含显式插入的键。
每个 Object 都有原型, 原型链上的键名有可能和你设置的键名产生冲突
- 键的顺序
Map 中的 key 是按照插入的顺序保存的.
Object中的键是没有任何顺序的.
- 值的数量
Map中可以通过size,获取值的数量,
Object 只能通过遍历统计.
- 性能
map在频繁增删键值对的场景下表现更好。
如果给固定的内存大小,Map可以比Objct多存储50%
四、总结
- 大多数场景下,选择map还是set是个人偏好问题,影响不大.
- map可以通过set()设置,get()获取,has() 判断是否存在,size 返回长度.
- 如果仅仅是为了存储数据,不牵扯oop,大家还是更多的使用map吧.
别跑,据说给我一键三联的人写代码都没Bug! 您的支持就是我最大的动力!
我是飞翔,
愿您日有所长