一文搞懂ES6的Map

2023-11-05

什么是Map

Map是ECMAScript 6 的新增特性,是一种新的集合类型,为javascript带来了真正的键/值存储机
制。

  • Map 对象存有键值对,其中的键可以是任何数据类型。

  • Map 对象记得键的原始插入顺序。

  • Map 对象具有表示映射大小的属性。

Map的基本API

1、new Map() 创建新的 Map 对象

使用 new 关键字和 Map 构造函数可以创建一个空映射:

// 创建新的 Map 对象。
const m = new Map();

如果想在创建的同时初始化实例,可以给 Map 构造函数传入一个可迭代对象,需要包含键/值对数
组。可迭代对象中的每个键/值对都会按照迭代顺序插入到新映射实例中

const m1 = new Map([ 
 ["key1", "val1"], 
 ["key2", "val2"], 
 ["key3", "val3"] 
]); 
alert(m1.size)  // 3
console.log(m1)

console打印出的m1如下:

使用自定义迭代器初始化映射

// 使用自定义迭代器初始化映射
const m2 = new Map({ 
 [Symbol.iterator]: function*() { 
 yield ["key1", "val1"]; 
 yield ["key2", "val2"]; 
 yield ["key3", "val3"]; 
 } 
}); 
alert(m2.size); // 3
console.log(m2)

console打印出的m2如下:

set()、 get()、has()、delete()、clear()

初始化之后,可以使用 set()方法再添加键/值对。另外,可以使用 get()和 has()进行查询,可
以通过 size 属性获取映射中的键/值对的数量,还可以使用 delete()和 clear()删除值。

  • set()方法再添加键/值对
  • get()获取 Map 对象中键的值
  • has()进行查询
  • delete()删除一个键/值对
  • clear()清除这个映射实例中的所有键/值对
const m = new Map(); 
alert(m.has("firstName")); // false 
alert(m.get("firstName")); // undefined 
alert(m.size); // 0 
m.set("firstName", "Matt") 
 .set("lastName", "Frisbie"); 
alert(m.has("firstName")); // true 
alert(m.get("firstName")); // Matt 
alert(m.size); // 2 
m.delete("firstName"); // 只删除这一个键/值对
alert(m.has("firstName")); // false 
alert(m.has("lastName")); // true 
alert(m.size); // 1 
m.clear(); // 清除这个映射实例中的所有键/值对
alert(m.has("firstName")); // false 
alert(m.has("lastName")); // false 
alert(m.size); // 0

set()方法返回映射实例,因此可以把多个操作连缀起来,包括初始化声明:

const m = new Map().set("key1", "val1");
m.set("key2", "val2")
    .set("key3", "val3");
alert(m.size); // 3

与 Object 只能使用数值、字符串或符号作为键不同,Map 可以使用任何 JavaScript 数据类型作为
键。

const m = new Map(); 
const functionKey = function() {}; 
const symbolKey = Symbol(); 
const objectKey = new Object(); 
m.set(functionKey, "functionValue"); 
m.set(symbolKey, "symbolValue"); 
m.set(objectKey, "objectValue"); 
alert(m.get(functionKey)); // functionValue 
alert(m.get(symbolKey)); // symbolValue 
alert(m.get(objectKey)); // objectValue

Map的顺序与迭代

与 Object 类型的一个主要差异是,Map 实例会维护键值对的插入顺序,因此可以根据插入顺序执
行迭代操作。
Map映射实例可以提供一个迭代器(Iterator),能以插入顺序生成[key, value]形式的数组。

entries() 返回 Map 对象中键/值对的数组。

Map映射实例提供一个迭代器(Iterator),能以插入顺序生成[key, value]形式的数组。可以
通过 entries()方法(或者 Symbol.iterator 属性,它引用 entries())取得这个迭代器:

const m = new Map([ 
 ["key1", "val1"], 
 ["key2", "val2"], 
 ["key3", "val3"] 
]); 
alert(m.entries === m[Symbol.iterator]); // true 
for (let pair of m.entries()) { 
 alert(pair); 
} 
// [key1,val1] 
// [key2,val2] 
// [key3,val3] 
for (let pair of m[Symbol.iterator]()) { 
 alert(pair); 
} 
// [key1,val1] 
// [key2,val2] 
// [key3,val3]

因为 entries()是默认迭代器,所以可以直接对映射实例使用扩展操作,把映射转换为数组:

const m = new Map([ 
 ["key1", "val1"], 
 ["key2", "val2"], 
 ["key3", "val3"] 
]); 
console.log([...m]); // [[key1,val1],[key2,val2],[key3,val3]]

如果不使用迭代器,而是使用回调方式,则可以调用映射的 forEach(callback, opt_thisArg)
方法并传入回调,依次迭代每个键/值对。

const m = new Map([ 
 ["key1", "val1"], 
 ["key2", "val2"], 
 ["key3", "val3"] 
]); 
m.forEach((val, key) => alert(`${key} -> ${val}`)); 
// key1 -> val1 
// key2 -> val2 
// key3 -> val3
keys()和 values()分别返回以插入顺序生成键和值
const m = new Map([
    ["key1", "val1"],
    ["key2", "val2"],
    ["key3", "val3"]
]);
for (let key of m.keys()) {
    alert(key);
}
// key1 
// key2 
// key3 
for (let key of m.values()) {
    alert(key);
}
// value1 
// value2 
// value3

选择object还是map

Map 的大多数特性都可以通过 Object 类型实现,但二者之间还是存在一些细微的差异。
对于大部分业务开发者来说,选择object还是map只是个人喜好问题,其实影响不大。
但是对于追求业务和性能的开发者来说,object和map确实存在很大的区别。
在具体实践中使用哪一个,还是值得细细甄别。

1. 内存占用

同一浏览器中给定固定大小的内存,Map 大约可以比 Object 多存储 50%的键/值对。

2. 插入性能

向 Object 和 Map 中插入新键/值对的消耗大致相同,不过插入 Map 在所有浏览器中一般会稍微快
一点儿。对这两个类型来说,插入速度并不会随着键/值对数量而线性增加。如果代码涉及大量插入操
作,那么显然 Map 的性能更佳。

3. 查找速度

与插入不同,从大型 Object 和 Map 中查找键/值对的性能差异极小,但如果只包含少量键/值对,
则 Object 有时候速度更快。如果代码涉及大量查找操作,那么某些情况下可能选
择 Object 更好一些。

4、删除性能

对大多数浏览器引擎来说,Map 的 delete()操作都比插入和查找更快。
如果代码涉及大量删除操作,那么毫无疑问应该选择 Map。

文章参考自《JavaScript高级程序设计第四版》

欢迎关注我的个人微信公众号:javascript艺术

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一文搞懂ES6的Map 的相关文章

随机推荐

  • 如何搭建个人博客(详细图解)

    本文共计7000余字 总框架 一目标 搭建个人博客 二各种搭建途径 途径1 略 途径2 2 1利用emlog 宝塔面板 服务器建立网站 123 112233 我的 https justgogoal com 2020 07 09 22 39
  • hook介绍

    一 hook 钩子 按照生命周期和功能进行封装 优势 逻辑简化 而 钩子 的意思 就是在事件传送到终点前截获并监控事件的传输 像个钩子钩上事件一样 并且能够在钩上事件时 处理一些自己特定的事件 1 要启用Hooks 所有React软件包都必
  • Linux free -m 详细说明

    free 命令相对于top 提供了更简洁的查看系统内存使用情况 free total used free shared buffers cached Mem 255268 238332 16936 0 85540 126384 buffer
  • video切换清晰度_移动端浏览器中的视频分辨率切换方案

    在常见的视频 APP 中 几乎都实现了视频分辨率切换功能 其中有一些会在点击切换分辨率后继续播放当前分辨率视频 稍有延迟后切换到新的分辨率视频 实现了视频分辨率的无缝切换 那么在移动端网页中 我们该如何实现视频分辨率的切换甚至无缝切换功能呢
  • k8s安装部署apollo配置中心

    一 文章大纲 二 安装MySQL5 7 三 创建apollo config 四 创建apollo admin 五 创建apollo portal 六 查看apollo各个组件服务状态 七 访问apollo 八 nginx代理配置转发 注意
  • 实验6 Sniffer网络安全检测

    实验6 Sniffer网络安全检测 实验目的 实验环境与设备 实验要求 过程如下 实验目的 掌握利用Sniffer软件捕获网络信息数据包 同时通过数据包的分层解析 进行状态分析 掌握网络安全检测工具的实际操作方法 完成检测报告 并写出结论
  • powershell cs-UTF-16LE编码上线

    0x01前言 当我们要上线主机的时候 可能会因为你的代码含有木马字符串 导致无法上线 0x02问题 1 例子 powershell exe exec bypass encodedCommand ZQBjAGgAbwAgACIAMQAyADM
  • Limited access In Sharepoint 2010

    When a security principal is added to the scope of an item with unique permissions the security principal is immediately
  • css穿透(带案例详解)

    问题背景 在使用vue构建项目的时候 引用了第三方组件库 只需要在当前页面修改第三方组件库的样式 以做到不污染全局样式 通过在样式标签上使用scoped 达到样式只作用到本页面的目的 但是此时再修改组件样式就不起作用了 div class
  • qt creator中Q_OBJECT导致出现undefined reference to vtable for 的错误

    在qt creator中新建了一个c 的类 刚开始编译可以通过 后来不知道为什么突然就编译报错 出现了undefined reference to vtable for 的错误 一开始以为是语法错误 结果找了很久都没有找到错误 后来发现把该
  • 构建SOA架构(笔记)

    1 什么是SOA架构设计师与设计和开发人员之间的差别呢 相信这些都是使大家最容易产生迷惑的问题 举个实际的例子来说 当构建一个基于SOA架构的系统的时候 针对一个具体的 service 系统设计人员主要应该关注的是这个service能够为外
  • Android uiautomatorviewer无法启动

    Android uiautomatorviewer无法启动 uiautomatorviewer 是android sdk提供的用来抓取布局的工具 然而有时候会出现无法启动 点击闪退的现象 先说原因 JDK版本高于java8 google 没
  • 异常org.hibernate.HibernateException: The database returned no natively generated identity解决方案

    配置文件
  • php 优化代码教程,PHP代码性能优化的技巧讲解_PHP教程

    PHP代码性能优化1 不要随便就复制变量 有时候为了使 PHP 代码更加整洁 一些 PHP 新手 包括我 会把预定义好的变量复制到一个名字更简短的变量中 其实这样做的结果是增加了一倍的内存消耗 只会使程序更加慢 试想一下 在下面的例子中 如
  • 使用py2neo创建知识图谱报错The following settings are not supported:{‘http_port‘:7474}

    今天在运行创建知识图谱的代码时 报以下错 The following settings are not supported http port 7474 再查看一下自己的py2neo版本 发现是由于版本太高了 将版本降低后就可以运行了 我这
  • js取整数、取余数、取小数点后几位的方法

    取整 1 取整 丢弃小数部分 保留整数部分 parseInt 5 2 2 2 向上取整 向上取整 有小数就整数部分加1 Math ceil 5 2 3 3 向下取整 向下取整 丢弃小数部分 Math floor 5 2 2 4四舍五入 四舍
  • hexo博客网站搭建

    Hexo简介 Hexo 是一个快速 简洁且高效的博客框架 Hexo 使用 Markdown 或其他渲染引擎 解析文章 在几秒内 即可利用靓丽的主题生成静态网页 安装前提 在安装Hexo之前需要安装以下应用 Node js Git markd
  • VS Code安装教程

    一 下载 1 官网 下载地址 2 下载 根据自己电脑型号下载 此处以Windows为例 二 安装 1 下载完成后 直接点击安装包安装 即可 2 开始安装 然后下一步 3 可以在此处自定义地址 然后下一步 4 默认设置 下一步 5 设置系统的
  • c# websocketServer base64乱码

    下载地址 https download csdn net download peiranshuiyu 10168136 这个接收图片base64乱码 后来查原因 byte 102400 的参数 太短不能完整接收 太长又乱码 后来调成1024
  • 一文搞懂ES6的Map

    什么是Map Map是ECMAScript 6 的新增特性 是一种新的集合类型 为javascript带来了真正的键 值存储机 制 Map 对象存有键值对 其中的键可以是任何数据类型 Map 对象记得键的原始插入顺序 Map 对象具有表示映