介绍
Map(映射)是 ECMAScript 6 规范中引入的一种数据结构,是一种存储键值对列表很方便的方法,类似于其他编程语言中的词典或者哈希表。它提供了“值-值”的对应,是一种更完善的 Hash 结构的实现。
常用的 Map方法有:赋值 — set(key,value),获取 — get(key),移除指定键名及其对应的值 — delete(key),判断是否存在 — has(key),获取所有值 — values()、key/value,迭代器 — entries(),清空所有键值对 — clear()等。
本质上 Map(映射) 就是一个 Object 对象。
使用
Map()是JavaScript中内置的一种数据结构,它允许您将键值对映射到任意类型的值。Map()的使用非常简单,可以通过以下方式创建一个新的Map()实例。
const myMap = new Map();
Map.set()
该方法接受两个参数,可用于为数据类型 Map 赋值 map.set(key,value)
,可增加新的键/值对或者修改键/值对,返回整个 Map
对象。
myMap.set(key, value);
key
:要添加至相应 Map 对象的元素的键。value
:要添加至相应 Map 对象的元素的值。
其返回的是一个 Map 对象。
const page_info = new Map()
// 利用 Map.set() 设置值
page_info.set("key", {
"keywords": "Map",
"description":"Map对象是一种简单的键/值映射"
});
console.log(page_info);
page_info.set("key", "key信息");
console.log(page_info);
其输出内容,如下所示:
Map {
'key' => {
keywords: 'Map',
description: 'Map对象是一种简单的键/值映射'
}
}
Map { 'key' => 'key信息' }
实现了为 Map 对象新增值,并且利用 set() 方法修改了其中的值。
Map.get()
要从 Map 中获取值,可使用 Map.get() 方法,该方法接受一个键作为参数,返回此键对应的值。
myMap.get(key);
key
:必须参数,也是它唯一的参数,要从目标 Map 对象中获取的元素的键。
如果找不到这个值,就返回 undefined。
const page_info = new Map();
page_info.set("title", "javascript中的map");
const title = page_info.get("title");
const key = page_info.get("key");
console.log(title); // javascript中的map
console.log(key); // undefined
Map.delete()
map.delete(key)删除指定 key 的键值对,返回成功或失败结果,删除成功返回 true,删除失败返回 false。
myMap.delate(key)
- key:必须,要从 Map 对象中移除的元素的键。
其返回值是一个 boolean 值,如果 Map 对象中存在该元素,则移除它并返回 true;否则如果该元素不存在则返回 false。
const page_info = new Map();
page_info.set("title", "javascript中的map");
page_info.set("author", "in");
console.log(page_info);// Map {'title' => 'javascript中的map', 'author' => 'in' }
const deleted_author = page_info.delete("author");
const deleted_key = page_info.delete("key");
console.log(deleted_author); // true
console.log(deleted_key); // false
console.log(page_info);
Map.has()
Map.has(key),判断指定的 key 是否存在。
key,必须,用来检测是否存在指定元素的键值。
返回的是一个 boolean 值,如果指定元素存在于 Map 对象中,则返回 true,其他情况返回 false。
const page_info = new Map();
page_info.set("title", "javascript中的map");
console.log(page_info); // Map { 'title' => 'javascript中的map' }
console.log(page_info.has("title")); // true
console.log(page_info.has("key")); // false
Map.values()
Map.values(),获取所有键的值,返回一个新的 Map 的可迭代对象。
const page_info = new Map();
page_info.set("title", "javascript中的map");
page_info.set("author", "in");
console.log(page_info.values()); // [Map Iterator] { 'javascript中的map', 'in' }
Map.entries()
Map.entries(),返回一个新的包含 [key,value] 的 Iterator 对象,返回的迭代器的迭代顺序与 Map 对象的插入顺序相同。
const page_info = new Map();
page_info.set("title", "javascript中的map");
page_info.set("author", "in");
console.log(page_info.entries());
返回结果如下所示:
[Map Entries] {
[ 'title', 'javascript中的map' ],
[ 'author', 'in' ]
}
Map.clear()
Map.clear(),移除 Map 对象中的所有元素。
该方法会清除 Map 对象中的所有元素,并返回 undefined。
const page_info = new Map();
page_info.set("title", "javascript中的map");
page_info.set("author", "in");
page_info.clear();
console.log(page_info); // Map {}
数据转换
Map 是一个集合,可以与数组、对象进行转换。
转为数组
Map 转换为数组的方法,最简便的就是使用位扩展符 ···,如下所示:
const page_info = new Map();
page_info.set("title", "javascript中的map");
page_info.set("author", "in");
console.log([...page_info]);
// [ [ 'title', 'javascript中的map' ], [ 'author', 'in' ] ]
转为对象 Object
function mapToObj(map) {
const obj = Object.create(null);
map.forEach((v,k)=>{
obj[k] = v;
});
return obj;
}
const page_info = new Map();
page_info.set("title", "javascript中的map");
page_info.set("author", "in");
console.log( mapToObj(page_info));
输出结果为:
[Object: null prototype] {
title: 'javascript中的map',
author: 'in'
}
转为 JSON
Map 转化为 JSON,步骤是先把 Map 转化为对象,然后使用 JSON.stringify 方法,如下所示:
function mapToObj(map) {
const obj = Object.create(null);
map.forEach((v,k)=>{
obj[k] = v;
});
return obj;
}
function mapToJson(map){
return JSON.stringify(mapToObj(map));
}
const page_info = new Map();
page_info.set("title", "javascript中的map");
page_info.set("author", "in");
console.log( mapToJson(page_info));
// {"title":"javascript中的map","author":"in"}
对象转为 Map
对象转换为 Map 映射是通过 Object.entries() 来实现的。
const page_info = {
title:"javascript中的map",
author:"in"
};
console.log(new Map(Object.entries(page_info)));
// Map { 'title' => 'javascript中的map', 'author' => 'in' }
数组转为 Map
将数组传入 Map 构造函数即可,即 new Map(array),如下所示:
const page_info = [
["title","javascript中的map"],
["author","in"]
];
console.log(new Map(page_info));
// Map { 'title' => 'javascript中的map', 'author' => 'in' }
Object 与 Map
根据定义,Object 和 Map 是基于相同的概念,使用键值对来存储值。但是两者之间也有很大的不同,具体如下所示:
- key字段:在 Object 中,遵循普通字典的规则。键必须是简单类型,即整数或字符串或符号。但是在 Map 中,它可以是任何数据类型(对象、数组等)。
- 元素顺序:在 Map 中,元素(对)的原始顺序被保留,而在 Object 中不会。
- 继承:Map 是 Object 的一个实例,但是 Object 绝对不是 Map 的实例。
虽然 Map 看着比 Object 更有优势,但是仍然有一些情况 Object 表现🉐️比 Map 更好。则什么情况下使用 Map,什么情况下使用 Object,可以参考下面几点:
- 当只需要简单的结构来存储数据并且知道所有键都是字符串或整数(或符号)时,
Object
是一个很好的选择,因为创建普通对象并使用特定键访问对象的属性比创建一个Map
快得多。 - 当在需要将单独的逻辑应用于单个属性/元素的场景中,
Object
绝对是最佳选择。 Map
是纯粹的哈希,Object
不止于此(支持内部逻辑)。如果需要大量添加和删除属性的情况下,Map
可能会表现得更好。Map
保留其键的顺序,并且Map
的构建考虑到了迭代,所以如果迭代或元素顺序非常重要。Map
在存储大量数据时往往表现更好,尤其是当键在运行时未知,并且所有键的类型和所有值的类型都相同时。
总结
除了以上用法,Map 还可以用于缓存,因为键值对的底层数据结构非常迅速,并且易于检索和更新。同时, Map() 使得在循环过程中使用键也非常容易,对于需要遍历多个数组或对象时非常有用。除此之外,Map()还可以实现快速且可定制的文本翻译,即将所有文本放在一个 Map()中,然后根据当前语言选择键对应的翻译即可。如下所示:
const translations = new Map([
["Hello", {
"en-US": "Hello",
"zh-CN": "你好",
"fr-FR": "Bonjour"
}],
["Goodbye", {
"en-US": "Goodbye",
"zh-CN": "再见",
"fr-FR": "Au revoir"
}]
]);
function translate(text, language) {
return translations.get(text)[language];
}
console.log(translate("Hello", "zh-CN")); //输出:"你好"
Map()是JavaScript中一种快速、灵活的数据结构,支持任意类型的键和可扩展的属性和方法。它在许多情况下都非常实用,包括缓存数据、带键的循环以及文本翻译。如果您需要一个快速而灵活的数据结构来存储和检索键值对,请考虑使用JavaScript中的Map()。