前端 - Map对象详解_前端map-程序员宅基地

技术标签: 前端  

一、Map对象

1. 初始化Map

使用Array
let obj = new Map([[1, "111"], [2, "222"], [3, "333"]])
 
console.log(obj); // Map(4) {1 => '111', 2 => '222', 3 => '333'}
使用set() 方法
let obj = new Map();
 
obj.set(1, '111');
obj.set(2, '222');
obj.set(3, '333');

console.log(obj); // Map(4) {1 => '111', 2 => '222', 3 => '333'}

2. 内置方法

get() 方法

该方法返回key对应的value,如果不存在,则返回undefined。

let obj = new Map();
 
obj.set(1, '111');

console.log(obj.get(1)); // '111'
console.log(obj.get(2)); // undefined
has() 方法

该方法用于检查Map是否有指定key对应的value。

let obj = new Map();
 
obj.set(1, '111');

console.log(obj.has(1)); // true
console.log(obj.has(2)); // false
clear() 方法

该方法用于清空指定map对象中的所有内容。

let obj = new Map();
obj.set(1, '111');
console.log(obj); //  Map(1) {1 => '111'}

obj.clear();
console.log(obj); // Map(0) {size: 0}
delete() 方法

该方法用于删除map中指定key对应的一组key-value元素。

let obj = new Map();
 
obj.set(1, '111');
console.log(obj.get(1)); // '111'
console.log(obj.has(1)); // true

obj.delete(1)
console.log(obj.get(1)); // undefined
console.log(obj.has(1)); // false

3. Map遍历的方式

keys() 方法

该方法返回Map对象中每个元素的key。

let obj = new Map();
 
obj.set(1, '111');
obj.set(2, '222');
obj.set(3, '333');

console.log(obj.keys()); // MapIterator {1, 2, 3}
values() 方法

和keys方法对应,values方法返回的就是Map对象中的value集合。

let obj = new Map();
 
obj.set(1, '111');
obj.set(2, '222');
obj.set(3, '333');

console.log(obj.values()); // MapIterator {'111', '222', '333'}
entries() 方法

该方法返回Map集合中每个 [key,value] 元素的对象。

let obj = new Map();
 
obj.set(1, '111');
obj.set(2, '222');
obj.set(3, '333');

console.log(obj.entries()); // MapIterator {1 => '111', 2 => '222', 3 => '333'}
遍历
for (const [key, value] of obj.entries()) {
    console.log(key, value);
}
obj.forEach((value, key) => {
    console.log(key, value);
})
1 '111'
2 '222'
3 '333'

4. Map 的特点

  • Map 默认情况下不包含任何键,所有键都是自己添加进去的。不同于 Object 原型链上有一些默认的键。
  • Map 的键可以是任意类型数据,就连函数都可以。
  • Map 的键值对个数可以轻易通过size属性获取,Object 需要手动计算。
  • Map 在频繁增删键值对的场景下性能要比 Object 好。

5. 什么时候用 Map

  • 要添加的键值名和 Object 上的默认键值名冲突,又不想改名时,用 Map
  • 需要 String 和 Symbol 以外的数据类型做键值时,用 Map
  • 键值对很多,有需要计算数量时,用 Map
  • 需要频繁增删键值对时,用 Map

二、Map对象和普通对象的区别

在 JavaScript 中,普通对象和 ES6 的新对象 Map 都可以存储键值对,但还是有些区别。

1. 初始化与使用

普通对象可以直接使用字面量进行初始化,而 Map 需要 Map() 构造函数进行初始化,如果想要有初始值,则需要传递一个数组或其他元素为键值对的可迭代对象。这些键值对中的每一个都将被添加到一个新的 Map 中。

let a = {
    1: "111",
    2: "222",
    3: "333",
    0: "000",
}

let b = new Map([[1, "111"], [2, "222"], [3, "333"], [0,"000"]])

2. 密钥类型

Map类似于对象,但是键名不限于字符串,可以说Object结构提供键-值对应,Map结构提供值-值对应因此其实采用map结构会优于传统对象。

普通对象只能用字符串作为键名,而 Map 可以接受任何类型的键值(包括函数、对象或任何原语)。

const obj = {};
const map = new Map();
const key = function () {};
obj[key] = 1;
map.set(key, 1);

console.log('obj: ', obj); // { 'function () {}': 1 }
console.log('map: ', map); // Map(1) { [Function: key] => 1 }

3. Accidental keys

普通对象从原型继承了许多属性键,例如构造函数等。因此,自己的密钥很可能与原型上的密钥发生冲突。但是 Map 默认不包含任何键,它只包含那些显式放入的。

const obj = {};
const map = new Map();
console.log(obj.constructor); // ƒ Object() { [native code] }
console.log(map.get('constructor')); // undefined

4. Key order

虽然现在对普通对象的键进行了排序,但情况并非总是如此,而且排序很复杂。例如,如果对象中有键需要转换为字符串,则不保留对象键的原始顺序。虽然 Map 以简单的方式排序,但它始终与我们插入的顺序相同。

let a = {
    1: "111",
    2: "222",
    3: "333",
    0: "000",
}
let b = new Map([[1, "111"], [2, "222"], [3, "333"], [0,"000"]])

console.log(a);  // {0: '000', 1: '111', 2: '222', 3: '333'}
console.log(Object.keys(a));  // ['0', '1', '2', '3']
console.log(b); // Map(4) {1 => '111', 2 => '222', 3 => '333', 0 => '000'}

5. 迭代

可以使用 for…of 语句或 Map.prototype.forEach 直接迭代 Map 的属性,而普通对象不能直接迭代

let b = new Map([[1, "111"], [2, "222"]])

for (const [key,value] of b) { console.log(key, value)}
// 1 111
// 2 222

6. 序列化和解析

普通对象支持 JSON 序列化,但 Map 默认无法获取正确数据

const obj = {
  name: 1,
  age: 2,
};
const map = new Map([
  ['name', 1],
  ['age', 2],
]);
console.log(JSON.stringify(obj)); // "{"name":1,"age":2}"
console.log(JSON.stringify(map)); // "{}"

7. 性能

Map 对象在涉及频繁添加和删除键值对的场景中表现更好,而普通对象没有优化。

8. 总结

那么普通对象应该被 Map 对象替换吗?

不,如果我们想在 JSON 和原始数据之间转换或包含特定的业务逻辑,那么我们应该使用普通对象。因为当我们只想存储键值对和循环操作或不断添加和删除属性时,使用 Map 对象是更好的选择。

Map对象虽然也是继承自底层的Object.prototype ,但它为我们提供了很多实用的方法来减轻我们的认知负担,比普通对象更高级。

三、Map 和 WeakMap 区别

WeakMap是 ES6 中新增的一种集合类型,叫做“弱映射”。它和Map是兄弟关系,与Map的区别就在于这个弱字,API 还是Map的那套(只有set get has delete)

WeakMap 其实描述的是 JS 中垃圾回收程序对待“弱映射”中键的方式

1. WeakMap 的特性

  • WeakMap 只能将对象作为键名
  • WeakMap 的键名引用的对象是弱引用
  • WeakMap 不可遍历

2. Map 和 WeakMap 区别

  • Map 的键可以是任意类型,WeakMap 只接受对象作为键(null除外),不接受其他类型的值作为键
  • Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键; WeakMap 的键是弱引用,键所指向的对象可以被垃圾回收,此时键是无效的
  • Map 可以被遍历, WeakMap 不能被遍历

3. WeakMap 的使用场景

  • DOM 节点元数据
  • 部署私有属性
  • 数据缓存

参考链接:
详细了解JS Map,它和传统对象有什么区别?
Map对象和普通对象的7个区别
浅析 Map 和 WeakMap 区别以及使用场景

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/kelly0721/article/details/126783347

智能推荐

java Compiler API (java编译api)-程序员宅基地

文章浏览阅读1.3w次,点赞20次,收藏53次。在早期的版本中(Java SE5及以前版本)中只能通过tools.jar中的com.sun.tools.javac包来调用Java编译器,但由于tools.jar不是标准的Java库,在使用时必须要设置这个jar的路径。而在Java SE6中为我们提供了标准的包来操作Java编译器,这就是javax.tools包。编译java文件使用Java API来编译Java源代码有非常多方法,目前让..._java compiler api

matlab绘制球面模型_MATLAB采用surf/surfc/surfl/surfnorm绘制球体-程序员宅基地

文章浏览阅读2.1k次。利用绘制球体sphere(n),展示了MATLAB中的surf,surfc,surfl,surfnorm,surface五个绘图命令。启动MATLAB,新建脚本(Ctrl+N),输入如下代码:close all; clear all; clcn=20;[x,y,z]=sphere(n);figure(1);surf(x,y,z);axis equalfigure(2);surfc(x,y,z);a..._利用sphere(n)产生绘制球面数据,其中的n取值为学号后两位(若后两位小于等于5,需要

C语言单元测试---cunit(一) ---- 博客经典;_cu_assert_equal-程序员宅基地

文章浏览阅读1w次。C语言单元测试http://blog.csdn.net/colin719/article/details/1420583对于敏捷开发来说,单元测试必不可少,对于Java开发来说,JUnit非常好,对于C++开发,也有CPPUnit可供使用,而对于传统的c语言开发,就没有很好的工具可供使用,可以找到的有这么几个工具:CuTest -- CuTest(Cute Test)是一个非常简单..._cu_assert_equal

sk_buf, 再转载,太经典了 - 网络协议栈分析 - 草本植物_skbuf-程序员宅基地

文章浏览阅读4k次。本文转自: http://www.360doc.com/content/09/0205/16/36491_2466152.shtml#sk_buff结构可能是linux网络代码中最重要的数据结构,它表示接收或发送数据包的包头信息。它在中定义,并包含很多成员变量供网络代码中的各子系统使用。这个结构在linux内核的发展过程中改动过很多次,或者是增加新的选项,或者是重新组织已存在的_skbuf

怎么批量在数字里加入网页_手把手教你爬取天堂网1920*1080大图片(批量下载)——理论篇-程序员宅基地

文章浏览阅读1.2k次。/1 前言/平时我们要下载图片,要要一个一个点击下载是不是觉得很麻烦?那有没有更加简便的方法呢?答案是肯定的,这里我们以天堂网为例,批量下载天堂网的图片。/2 项目准备工作/首先 我们第一步我们要安装一个pycham的软件。可以参考这篇文章:Python环境搭建—安利Python小白的Python和Pycharm安装详细教程。天堂网的网址:https://www.ivsky.com/bizhi/1...

传奇假人自动上线_传奇商业脚本 各种M2防假人脚本大集合 传奇私服脚本-程序员宅基地

文章浏览阅读4.9k次。各种M2防假人脚本大集合BLUE的M2防假人攻击脚本:首先先在D:\MirServer\Mir200\Envir\QuestDiary\数据文件 目录下建一个“激活.txt”文本文挡其次在D:\MirServer\Mir200\Envir\MapQuest_def 目录下的QManage.txt脚本里加上如下一段[@Login]#ifchecknamelist ..\QuestDiary\数据文件..._传奇防挂机流星验证

随便推点

解题报告 (十三) 尺取法_尺取法课后作业 答 题 卡 上 一 题 下 一 题 2. k13629 字符计数 题目描述 给定一-程序员宅基地

文章浏览阅读2.8w次,点赞2次,收藏7次。解题报告 破折号 最简单的算法_尺取法课后作业 答 题 卡 上 一 题 下 一 题 2. k13629 字符计数 题目描述 给定一

北京理工大学计算机学院张教授,张子剑_北京理工大学计算机学院-程序员宅基地

文章浏览阅读490次。代表性学术成果1.Yiwei Liu, Jiamou Liu, Zijian Zhang, Liehuang Zhu, Ansheng Li. REM: From Structural Entropy To Community Structure Deception. NeurIPS 2019, Accepted, Vancouver, Canada.2.Liehuang Zhu, Meng ..._rem: from structural entropy to community structure deception

人工智能城市和智慧城市_智慧城市:人工智能在城市管理中的应用-程序员宅基地

文章浏览阅读4.9k次。人工智能城市和智慧城市Smart cities aren’t just sci-fi or cyberpunk dreams, but an actual solution based on Artificial Intelligence and the Internet of Things. But the question is, what is the mechanism that put ..._intelligent edge computing based on machine learning for smart city

[React-Native]样式和布局_reactnative内联样式怎么用-程序员宅基地

文章浏览阅读1.2w次。一、基本样式(1)内联样式 在组件里面定义样式 小字号内联样式(2)外联样式 在组件里指向外面的样式 大字号外联样式(3)样式具有覆盖性 如果定义相同属性的样式,后面会覆盖_reactnative内联样式怎么用

CH340串口转USB驱动安装-程序员宅基地

文章浏览阅读963次。驱动下载指南_串口转usb驱动

杰里之.V006 音箱版本删除录音文件,需要优化 system.a 库【篇】_ac6965a电路图-程序员宅基地

文章浏览阅读139次。// folder : /xxxxxx // filename : xxxx0000.yyy u8 file_api_delete_file(const char *path, const char *folder, const char *filename, u32 *file_index)_ac6965a电路图

推荐文章

热门文章

相关标签