悟透前端 | ECMAScript 6 的 Map 映射
source link: https://xie.infoq.cn/article/b12c6d6700992222617fb2e30
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
映射(Map)是 ECMAScript 6 规范中引入的一种数据结构。这是一种存储键值对列表很方便的方法,类似于其他编程语言中的词典或者哈希表。
什么是映射
javascript 的对象(Object),本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键,这给使用带来了很大的限制。为了解决这个问题,ECMAScript 6 引入了 Map 数据结构。它类似于对象,也是键值对的集合,但是"键"的范围不仅仅局限于字符串,而是各种类型的值(包括对象)都可以当作键。也就是说,Object 结构(对象结构)提供了"字符串—值"的对应,而 Map 结构提供了"值—值"的对应,是一种更完善的 Hash 结构的实现。
下面来看一个简单的示例,了解Map的基本用法:
//声明map实例 const page_info = new Map() // 向 map 中添加元素 page_info.set("seo", { "keywords": "infoq、Map", "description":"Map对象是一种简单的键/值映射,其中的键和值可以是任意值(原始值或对象的值)" }) page_info.set("title", "javascript es6的map映射") console.log(page_info) console.log(typeof page_info) // object
输出结果为:
Map { 'seo' => { keywords: 'infoq、Map', description: 'Map对象是一种简单的键/值映射,其中的键和值可以是任意值(原始值或对象的值)' }, 'title' => 'javascript es6的map映射' } object
从输出结果看,本质上Map(映射)就是一个
object
对象。
Object
与
Map
区别
Object
和
Map
的相似之处在于,都是按键存取一个值,而且键都是可以删除的。可以看出,二者之间是非常相似的,它的不同这之处在于:
MapObject意外的键
Map
默认情况不包含任何键。只包含显式插入的键。
一个
Object
有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
注意:
虽然 ES5 开始可以用
Object.create(null)
来创建一个没有原型的对象,但是这种用法不太常见。
键的类型一个
Map
的键可以是
任意值
,包括函数、对象或任意基本类型。一个
Object
的键必须是一个
String
或是
Symbol
。键的顺序
Map
中的 key 是有序的。因此,当迭代的时候,一个
Map
对象以插入的顺序返回键值。
一个
Object
的键是无序的
注意:自ECMAScript 2015规范以来,对象
确实
保留了字符串和
Symbol
键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。
size
Map
的键值对个数可以轻易地通过
size
属性获取
Object
的键值对个数只能手动计算迭代
Map
是 iterable 的,所以可以直接被迭代。迭代一个
Object
需要以某种方式获取它的键然后才能迭代。性能在频繁增删键值对的场景下表现更好。在频繁添加和删除键值对的场景下未作出优化。
Map映射常用方法
常用的 Map 方法有:赋值
set(key, value)
、获取
get(key)
、移除指定键名及其对应的值delete(key) 、判断是否存在
has(key)
、 获取所有值
values()
、
key/value
迭代器
entries()
、遍历
forEach()
和 清空所有键/值对
clear()
等。
声明并初始化
const new_map = new Map(); console.log(new_map); //输出:Map {}
赋值
set
赋值使用
map.set(key,value)
,可以用于增加新的
键/值
对或者修改
键/值
对,返回整个Map对象。
const page_info = new Map() // 设置值 page_info.set("seo", { "keywords": "infoq、Map", "description":"Map对象是一种简单的键/值映射,其中的键和值可以是任意值(原始值或对象的值)" }); console.log(page_info); page_info.set("seo", "seo信息"); console.log(page_info);
上面的示例增加值,并修改值。
Map { 'seo' => { keywords: 'infoq、Map', description: 'Map对象是一种简单的键/值映射,其中的键和值可以是任意值(原始值或对象的值)' } } Map { 'seo' => 'seo信息' }
获取键值
get
使用
get(key)
获取键值,如果获取的
key->value
不存则返回
undefined
const page_info = new Map(); page_info.set("title", "javascript es6的map映射"); const title = page_info.get("title"); const seo_info = page_info.get("seo"); console.log(title); //javascript es6的map映射 console.log(seo_info); //undefined
删除键值
delete
map.delete(key)
删除指定
key
的键值对,返回成功或失败结果,删除成功返回
true
,删除失败返回
false
。
const page_info = new Map(); page_info.set("title", "javascript es6的map映射"); page_info.set("author", "infoq"); console.log(page_info); // Map { 'title' => 'javascript es6的map映射', 'author' => 'infoq' } const deleted_author = page_info.delete("author"); const deleted_seo = page_info.delete("seo"); console.log(deleted_author); // true console.log(deleted_seo); // false console.log(page_info); // Map { 'title' => 'javascript es6的map映射' }
判断键值是否存在
has
使用
map.has(key)
判断指定
key
是否存在。
const page_info = new Map(); page_info.set("title", "javascript es6的map映射"); console.log(page_info); // Map { 'title' => 'javascript es6的map映射' } console.log(page_info.has("title")); // true console.log(page_info.has("seo")); // false
获取所有键值
values()
const page_info = new Map(); page_info.set("title", "javascript es6的map映射"); page_info.set("author", "infoq"); console.log(page_info.values()); // [Map Iterator] { 'javascript es6的map映射', 'infoq' }
key/value
迭代器
entries()
使用
map.entries()
返回一个包含Map对象中每一个
[key, value]
数组的Iterator迭代器。
const page_info = new Map(); page_info.set("title", "javascript es6的map映射"); page_info.set("author", "infoq"); console.log(page_info.entries());
输出的结果为:
[Map Entries] { [ 'title', 'javascript es6的map映射' ], [ 'author', 'infoq' ] }
遍历所有键值
forEach(callback)
const page_info = new Map(); page_info.set("title", "javascript es6的map映射"); page_info.set("author", "infoq"); page_info.forEach((value,key)=>{ console.log(key,value); });
输出的结果为:
title javascript es6的map映射 author infoq
清空Map映射所有键值
clear()
使用
map.clear()
清空Map所有的键值对。
const page_info = new Map(); page_info.set("title", "javascript es6的map映射"); page_info.set("author", "infoq"); page_info.clear(); console.log(page_info); // Map {}
与其它数据结构的转换
Map映射转为数组
Map转为数组最方便方法是使用扩展运算符
...
const page_info = new Map(); page_info.set("title", "javascript es6的map映射"); page_info.set("author", "infoq"); console.log([...page_info]); // [ [ 'title', 'javascript es6的map映射' ], [ 'author', 'infoq' ] ]
Map映射转为对象
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 es6的map映射"); page_info.set("author", "infoq"); console.log( mapToObj(page_info));
输出结果为:
[Object: null prototype] { title: 'javascript es6的map映射', author: 'infoq' }
数组转为Map映射
将数组传入Map构造函数即可,即
new Map(array)
。
const page_info = [ ["title","javascript es6的map映射"], ["author","infoq"] ]; console.log(new Map(page_info)); // Map { 'title' => 'javascript es6的map映射', 'author' => 'infoq' }
对象转为Map
对象转为Map映射通过
Object.entries()
。
const page_info = { title:"javascript es6的map映射", author:"infoq" }; console.log(new Map(Object.entries(page_info))); // Map { 'title' => 'javascript es6的map映射', 'author' => 'infoq' }
映射Map转为JSON
Map 转为 JSON ,步骤是先把Map转为对象,即前面的
mapToObj
,然后使用
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 es6的map映射"); page_info.set("author", "infoq"); console.log( mapToJson(page_info)); // {"title":"javascript es6的map映射","author":"infoq"}
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK