iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > node.js >在什么时候适合使用Map
  • 939
分享到

在什么时候适合使用Map

2024-04-02 19:04:59 939人浏览 安东尼
摘要

本篇内容介绍了“在什么时候适合使用Map”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!「Map」映射是一种

本篇内容介绍了“在什么时候适合使用Map”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

「Map」映射是一种经典的数据结构类型,其中数据以 「key/value」 的键值对形式存在

 MapObject
默认值默认不包含任何值,只包含显式插入的键一个 Object 有一个原型,原型上的键名有可能和自己对象上设置的键名冲突
类型任意String 或 Symbol
长度键值对个数通过 size 属性获取键值对个数只能手动计算
性能频繁增删键值对的场景下表现更好频繁添加和删除键值对的场景下未作出优化

Map 基本用法

const testMap = new Map()  let str = '今天不学习',      num = 666,      keyFunction = function () {},      keySymbol = Symbol('WEB'),      keyNull = null,      keyUndefined = undefined,      keyNaN = NaN  //添加键值对  //基本用法  testMap.set('key', 'value') // Map(1) {"key" => "value"}  testMap.set(str, '明天变辣鸡')  testMap.set(num, '前端Sneaker')  testMap.set(keyFunction, '你的函数写的好棒棒哦')  testMap.set(keySymbol, '大前端')  testMap.set(keyNull, '我是个Null')  testMap.set(keyUndefined, '我是个Undifined')  testMap.set(keyNaN, '我是个NaN')  testMap.get(function () {}) //undefined  testMap.get(Symbol('Web')) //undefined  //虽然NaN !== NaN 但是作为Map键名并无区别  testMap.get(NaN) //"我是个NaN"  testMap.get(Number('NaN')) //"我是个NaN"

除了NaN比较特殊外,其他「Map」的get方法都是通过对比键名是否相等(===)来获取,不相等则返回undefined

比较 Map 和 Object

定义

//Map  const map = new Map();  map.set('key', 'value'); // Map(1) {"key" => "value"}  map.get('key'); // 'value'  //Object  const someObject = {};  someObject.key = 'value';  someObject.key; // 'value'

这里可以明显看出其实其定义行为是十分相似的,想必看到这里大家还没看出来「Map」到底在何时使用才是最佳实践,别急接着来。

键名类型

javascript 「Object」只接收两种类型的键名 String 和 Symbol,你可以使用其他类型的键名,但是最终 JavaScript 都会隐式转换为字符串

const obj = {}  //直接看几种比较特殊的键名  obj[true] = 'Boolean'  obj[1] = 'Number'  obj[{'前端':'Sneaker'}] = '666'  Object.keys(obj) // ["1", "true", "[object Object]"]

再来看看 「Map」 的,其接收任何类型的键名并保留其键名类型 (此处简单举例,详细可看文章开头「Map」基本使用)

const map = new Map();  map.set(1, 'value');  map.set(true, 'value');  map.set({'key': 'value'}, 'value');  for (const key of map.keys()) {    console.log(key);  }  // 1  // true  // {key: "value"}  //除此之外,Map还支持正则作为键名  map.set(/^1[3456789]\d{9}$/,'手机号正则')  //Map(1) {/^1[3456789]\d{9}$/ => "手机号正则"}

「Map」支持正则表达式作为键名,这在Object是不被允许的直接报错

原型 Prototype

「Object」不同于「Map」,它不仅仅是表面所看到的。「Map」只包含你所定义的键值对,但是「Object」对象具有其原型中的一些内置属性

const newObject = {};  newObject.constructor; // ƒ Object() { [native code] }

如果操作不当没有正确遍历对象属性,可能会导致出现问题,产生你意料之外的 bug

在什么时候适合使用Map

const countWords = (words) => {    const counts = { };    for (const word of words) {      counts[word] = (counts[word] || 0) + 1;    }    return counts;  };  const counts = countWords(['constructor', 'creates', 'a', 'bug']);  // {constructor: "function Object() { [native code] }1", creates: 1, a: 1, bug: 1}

这个例子灵感来源于《Effective typescript》[1]一书

迭代器

「Map」 是可迭代的,可以直接进行迭代,例如forEach循环或者for...of...循环

//forEach  const map = new Map();  map.set('key1', 'value1');  map.set('key2', 'value2');  map.set('key3', 'value3');  map.forEach((value, key) => {    console.log(key, value);  });  // key1 value1  // key2 value2  // key3 value3  //for...of...  for(const entry of map) {    console.log(entry);  }  // ["key1", "value1"]  // ["key2", "value2"]  // ["key3", "value3"]

但是对于「Object」是不能直接迭代的,当你尝试迭代将导致报错

在什么时候适合使用Map

const object = {    key1: 'value1',    key2: 'value2',    key3: 'value3',  };  for(const entry of object) {    console.log(entry);  }  // Uncaught TypeError: object is not iterable

这时候你就需要一个额外的步骤来检索其键名、键值或者键值对

for(const key of Object.keys(object)) {    console.log(key);  }  // key1  // key2  // key3  for(const value of Object.values(object)) {    console.log(value); }  // value1  // value2  // value3  for(const entry of Object.entries(object)) {    console.log(entry);  }  // ["key1", "value1"]  // ["key2", "value2"]  // ["key3", "value3"]  for(const [key,value] of Object.entries(object)) {    console.log(key,value);  }  //"key1", "value1"  //"key2", "value2"  //"key3", "value3"

当然也可以使用for...in...进行遍历循环键名

for(const key in object) {    console.log(key);  }  // key1  // key2  // key3

元素顺序和长度

Map 保持对长度的跟踪,使其能够在O(1)复杂度中进行访问

const map = new Map();  map.set('key1', 'value1');  map.set('key2', 'value2');  map.set('key3', 'value3');  map.size; // 3

而另一方面,对于「Object」而言,想要获得对象的属性长度,需要手动对其进行迭代,使其为O(n)复杂度,属性长度为n

在上文提及的示例中,我们可以看到「Map」始终保持按插入顺序返回键名。但「Object」却不是。从 es6 开始,String和Symbol键是按顺序保存起来的,但是通过隐式转换保存成String的键就是乱序的

const object = { };  object['key1'] = 'value1';  object['key0'] = 'value0';  object; // {key1: "value1", key0: "value0"}  object[20] = 'value20';  object; // {20: "value20", key1: "value1", key0: "value0"}  Object.keys(object).length; //3

Object/Map 何为最佳实践

如上就是 「Map」 和 「Object」 的基本区别,在解决问题考虑两者的时候就需要考虑两者的区别。

  •  当插入顺序是你解决问题时需要考虑的,并且当前需要使用除 String 和 Symbol 以外的键名时,那么 「Map」 就是个最佳解决方案

  •  如果需要遍历键值对(并且需要考虑顺序),那我觉得还是需要优先考虑 「Map」。

  •  Map是一个纯哈希结构,而Object不是(它拥有自己的内部逻辑)。Map 在频繁增删键值对的场景下表现更好,性能更高。因此当你需要频繁操作数据的时候也可以优先考虑 Map

  •  再举一个实际的例子,比如有一个自定义字段的用户操作功能,用户可以通过表单自定义字段,那么这时候最好是使用 Map,因为很有可能会破坏原有的对象 

const userCustomFields = {    'color':    'blue',    'size':     'medium',    'toString': 'A blue box'  };

此时用户自定义的 toString 就会破坏到原有的对象 而 「Map」 键名接受任何类型,没有影响

function isMap(value) {    return value.toString() === '[object Map]';  }  const actORMap = new Map(); actorMap.set('name', 'Harrison Ford');  actorMap.set('toString', 'Actor: Harrison Ford');  // Works!  isMap(actorMap); // => true
  •  当你需要处理一些属性,那么 「Object」 是完全受用的,尤其是需要处理 JSON 数据的时候。由于 「Map」 可以是任意类型,因此没有可以将其转化为 jsON 的原生方法。 

var map = new Map()  map.set('key','value')  JSON.stringify(map)  //"{}"
  •  当你需要通正则表达式判断去处理一些业务逻辑时,「Map」将是你的最佳解决方案 

const actions = ()=>{    const functionA = ()=>{}    const functionB = ()=>{}    const functionC = ()=>{}    returnnewMap([      [/^guest_[1-4]$/,functionA],      [/^guest_5$/,functionB],      [/^guest_.*$/,functionC],      //...    ])  } const onButtonClick = (identity,status)=>{    let action = [...actions()].filter(([key,value])=>(key.test(`${identity}_${status}`)))    action.forEach(([key,value])=>value.call(this))  }

利用数组循环的特性,符合正则条件的逻辑都会被执行,那就可以同时执行公共逻辑和单独逻辑,因为正则的存在,你可以打开想象力解更多的玩法,更多相关 Map 用法样例可以查看JavaScript 复杂判断的更优雅写法

“在什么时候适合使用Map”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 在什么时候适合使用Map

本文链接: https://www.lsjlt.com/news/84800.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 在什么时候适合使用Map
    本篇内容介绍了“在什么时候适合使用Map”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!「Map」映射是一种...
    99+
    2024-04-02
  • JavaScript 中什么时候使用 Map 更好
    目录Map 用作 Hash Map性能基准测试的实现细节字符串类型的键整数类型的键数值类型的键内存使用总结浏览器兼容性笔记Map 用作 Hash Map ES6 给我们带来了&nbs...
    99+
    2024-04-02
  • 什么时候适合使用 C++ 函数单元测试?
    函数单元测试是一种自动化测试技术,用于隔离测试 c++++ 函数的预期行为。适用于以下场景:验证函数行为检查边界条件检测错误重构代码作为文档说明 何时使用 C++ 函数单元测试 函数单...
    99+
    2024-04-24
    c++ 单元测试 重构代码
  • 什么时候使用flags
    这篇文章主要讲解了“什么时候使用flags”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“什么时候使用flags”吧!   Possible flags:(...
    99+
    2024-04-02
  • HTML div什么时候使用
    本篇内容主要讲解“HTML div什么时候使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“HTML div什么时候使用”吧! 1、div:作为布局以及样式化...
    99+
    2024-04-02
  • c++中endl什么时候使用
    std::endl 用于将换行符写入流,通常在需要显式结束行时使用。它强制刷新流并避免缓冲行为。替代方法包括直接写入 '\n' 字符或使用 std::flush 手动刷新流。 什么时候...
    99+
    2024-04-28
    c++
  • JavaScript 什么时候使用回调
    JavaScript 什么时候使用回调,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 JavaScript 何时使用回调? ...
    99+
    2024-04-02
  • 什么时候使用Lambda函数?
    原文来自:1前言Python 中定义函数有两种方法,一种是用常规方式 def 定义,函数要指定名字,第二种是用 lambda 定义,不需要指定名字,称为 Lambda 函数。Lambda 函数又称匿名函数,匿名函数就是没有名字的函数,函数没...
    99+
    2023-06-02
  • 使用div+css布局过程中在什么时候使用table
    这篇文章主要讲解了“使用div+css布局过程中在什么时候使用table”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“使用div+css布局过程中在什么时候...
    99+
    2024-04-02
  • 什么时候应该使用 golang 函数?
    何时使用 go 函数?需要将代码分解成较小的块。需要重复使用代码。需要将代码逻辑封装到一个可重用的模块中。 何时使用 Go 函数 Go 中的函数是一种封装代码并将代码块组织在一起的方法...
    99+
    2024-04-25
    函数 golang
  • React组件在什么时候render
    这篇文章主要讲解了“React组件在什么时候render”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“React组件在什么时候render”吧!对于如下De...
    99+
    2024-04-02
  • java移位运算符在什么时候用
    Java移位运算符用于对一个数的二进制位进行移动。它们通常在以下情况下使用:1. 位运算:移位运算符可用于对整数进行位运算,如按位与...
    99+
    2023-08-29
    java
  • Java消息队列什么时候使用
    本篇内容主要讲解“Java消息队列什么时候使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java消息队列什么时候使用”吧!何时需要消息队列当你需要使用消息队列时,首先需要考虑它的必要性。可以...
    99+
    2023-06-04
  • mysql什么时候可以使用索引
    这篇文章主要介绍mysql什么时候可以使用索引,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!            &nb...
    99+
    2024-04-02
  • 什么时候需要使用HTTPS代理
    本篇文章给大家分享的是有关什么时候需要使用HTTPS代理,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。HTTPS是HTTP的安全版本,它在HTTP上建立SSL加密层并加密传输的...
    99+
    2023-06-25
  • Java匿名内部类在什么时候用
    Java匿名内部类通常在以下情况下使用:1. 当一个类只需要使用一次,并且这个类没有名字,可以使用匿名内部类来实现。这样可以避免创建...
    99+
    2023-08-15
    Java
  • O_SYNC什么时候起作用?
    本篇文章给大家分享《O_SYNC什么时候起作用?》,覆盖了Golang的常见基础知识,其实一个语言的全部知识点一篇文章是不可能说完的,但希望通过这些问题,让读者对自己的掌握程度有一定的认识(B 数)...
    99+
    2024-04-05
  • Go在什么时候会抢占P
    本篇内容主要讲解“Go在什么时候会抢占P”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Go在什么时候会抢占P”吧! 调度器的发展史在 Go 语言中,Goroutine 早期是没有设计成...
    99+
    2023-06-15
  • 什么时候使用HTML内部样式表
    这篇文章主要介绍“什么时候使用HTML内部样式表”,在日常操作中,相信很多人在什么时候使用HTML内部样式表问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”什么时候使用HTML...
    99+
    2024-04-02
  • HTML外部样式表什么时候使用
    这篇“HTML外部样式表什么时候使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“HTML...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作