Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。

语法

new Map([iterable])

参数

iterable
Iterable 可以是一个数组或者其他 iterable 对象,其元素或为键值对,或为两个元素的数组。 每个键值对都会添加到新的 Map。null 会被当做 undefined。

描述

一个Map对象以插入顺序迭代其元素 — 一个  for...of 循环为每次迭代返回一个[key,value]数组。

键的相等(Key equality)

键的比较是基于 "same-value" 算法:NaN 是与 NaN 相同的(虽然 NaN !== NaN),剩下所有其它的值是根据 === 运算符的结果判断是否相等。在 ECMAScript 6 草稿的早期版本中视 -0 和 +0 为不相同的 (虽然 -0 === +0),在近期版本里这个问题已经被更正,且在 Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26) (bug 952870) 和近期的 nightly Chrome 版本这个已经更改了。

Objects 和 maps 的比较

Object 和 Map类似的一点是,它们都允许你按键存取一个值,都可以删除键,还可以检测一个键是否绑定了值.因此,一直以来,我们都把对象当成Map来使用,不过,现在有了Map,下面的区别解释了为什么使用Map更好点.

  • 一个对象通常都有自己的原型,所以一个对象总有一个"prototype"键。不过,从 ES5 开始可以使用 map = Object.create(null)来创建一个没有原型的对象。
  • 一个对象的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值
  • 你可以通过size属性很容易地得到一个Map的键值对个数,而对象的键值对个数只能手动确认。

但是这并不意味着你可以随意使用 Map,对象仍旧是最常用的。Map 实例只适合用于集合(collections),你应当考虑修改你原来的代码——先前使用对象来对付集合的地方。对象应该用其字段和方法来作为记录的。
如果你不确定要使用哪个,请思考下面的问题:

  • 在运行之前 key 是否是未知的,是否需要动态地查询 key 呢?
  • 是否所有的值都是统一类型,这些值可以互换么?
  • 是否需要不是字符串类型的 key ?
  • 键值对经常增加或者删除么?
  • 是否有任意个且非常容易改变的键值对?
  • 这个集合可以遍历么(Is the collection iterated)?

假如以上全是“是”的话,那么你需要用 Map 来保存这个集。 相反,你有固定数目的键值对,独立操作它们,区分它们的用法,那么你需要的是对象。

属性

Map.length
属性 length 的值为 0 。
get Map[@@species]
本构造函数用于创建派生对象。
Map.prototype
表示 Map 构造器的原型。 允许添加属性从而应用于所有的 Map 对象。

Map 实例

所有的 Map 对象实例都会继承 Map.prototype

属性

Map.prototype.constructor
返回一个函数,它创建了实例的原型。默认是Map函数。
Map.prototype.size
返回Map对象的键/值对的数量。

方法

Map.prototype.clear()
移除Map对象的所有键/值对 。
Map.prototype.delete(key)
移除任何与键相关联的值,并且返回该值,该值在之前会被Map.prototype.has(key)返回为true。之后再调用Map.prototype.has(key)会返回false。
Map.prototype.entries()
返回一个新的 Iterator 对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组
Map.prototype.forEach(callbackFn[, thisArg])
按插入顺序,为 Map对象里的每一键值对调用一次callbackFn函数。如果为forEach提供了thisArg,它将在每次回调中作为this值。
Map.prototype.get(key)
返回键对应的值,如果不存在,则返回undefined。
Map.prototype.has(key)
返回一个布尔值,表示Map实例是否包含键对应的值。
Map.prototype.keys()
返回一个新的 Iterator对象, 它按插入顺序包含了Map对象中每个元素的
Map.prototype.set(key, value)
设置Map对象中键的值。返回该Map对象。
Map.prototype.values()
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的
Map.prototype[@@iterator]()
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组

示例

使用映射对象

var myMap = new Map(); var keyObj = {}, keyFunc = function () {}, keyString = "a string"; // 添加键 myMap.set(keyString, "和键'a string'关联的值"); myMap.set(keyObj, "和键keyObj关联的值"); myMap.set(keyFunc, "和键keyFunc关联的值"); myMap.size; // 3 // 读取值 myMap.get(keyString); // "和键'a string'关联的值" myMap.get(keyObj); // "和键keyObj关联的值" myMap.get(keyFunc); // "和键keyFunc关联的值" myMap.get("a string"); // "和键'a string'关联的值" // 因为keyString === 'a string' myMap.get({}); // undefined, 因为keyObj !== {} myMap.get(function() {}) // undefined, 因为keyFunc !== function () {}

将NaN作为映射的键

NaN 也可以作为Map对象的键. 虽然 NaN 和任何值甚至和自己都不相等(NaN !== NaN 返回true), 但下面的例子表明, 两个NaN作为Map的键来说是没有区别的:

var myMap = new Map(); myMap.set(NaN, "not a number"); myMap.get(NaN); // "not a number" var otherNaN = Number("foo"); myMap.get(otherNaN); // "not a number"

使用for..of方法迭代映射

映射也可以使用for..of循环来实现迭代:

var myMap = new Map(); myMap.set(0, "zero"); myMap.set(1, "one"); for (var [key, value] of myMap) { console.log(key + " = " + value); } // 将会显示两个log。一个是"0 = zero"另一个是"1 = one" for (var key of myMap.keys()) { console.log(key); } // 将会显示两个log。 一个是 "0" 另一个是 "1" for (var value of myMap.values()) { console.log(value); } // 将会显示两个log。 一个是 "zero" 另一个是 "one" for (var [key, value] of myMap.entries()) { console.log(key + " = " + value); } // 将会显示两个log。 一个是 "0 = zero" 另一个是 "1 = one"

使用forEach()方法迭代映射

映射也可以通过forEach()方法迭代:

myMap.forEach(function(value, key) { console.log(key + " = " + value); }, myMap) // 将会显示两个logs。 一个是 "0 = zero" 另一个是 "1 = one"

映射与数组对象的关系

var kvArray = [["key1", "value1"], ["key2", "value2"]];// 使用映射对象常规的构造函数将一个二维键值对数组对象转换成一个映射关系
var myMap = new Map(kvArray);myMap.get("key1"); // 返回值为 "value1"// 使用展开运算符将一个映射关系转换成一个二维键值对数组对象
console.log(uneval([...myMap])); // 将会向您显示和kvArray相同的数组// 或者使用展开运算符作用在键或者值的迭代器上,进而得到只含有键或者值得数组
console.log(uneval([...myMap.keys()])); // 输出 ["key1", "key2"]

规范

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
Map
Standard Initial definition.
ECMAScript Latest Draft (ECMA-262)
Map
Living Standard  

浏览器兼容情况

  • Desktop
  • Mobile
Feature Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari
Basic support

38 [1]

12 13 (13) 11 25 7.1
Constructor argument: new Map(iterable) 38 12 13 (13) 未实现 25 9
iterable 38 12 17 (17) 未实现 25 7.1
Map.clear() 31
38
12 19 (19) 11 25 7.1
Map.keys(), Map.values(), Map.entries() 37
38
12 20 (20) 未实现 25 7.1
Map.forEach() 36
38
12 25 (25) 11 25 7.1
Key equality for -0 and 0 34
38
12 29 (29) 未实现 25 9
Constructor argument: new Map(null) (Yes) 12 37 (37) 11 (Yes) 9
Monkey-patched set() in Constructor (Yes) 12 37 (37) 未实现 (Yes) 9
Map[@@species] 51 13 41 (41) 未实现 38 10
Map() without new throws (Yes) 12 42 (42) 11 (Yes) 9

[1] Starting with Chrome 31,the feature was available behind a preference. In chrome://flags, activate the entry “Enable Experimental JavaScript”.

转载于:https://www.cnblogs.com/h2zZhou/p/7477544.html

Map与object的区别相关推荐

  1. 原 c++中map与unordered_map的区别

    c++中map与unordered_map的区别 头文件 map: #include < map > unordered_map: #include < unordered_map ...

  2. TxQueryRunner类对结果集封装成bean、map及object的操作

    一.需要的jar包: itcast-tools-1.4.jar     http://pan.baidu.com/s/1Dbo2i commons-beanutils-1.8.3.jar    htt ...

  3. js数组中forEach/some/every/map/filter/reduce的区别

    2019独角兽企业重金招聘Python工程师标准>>> // js数组中forEach/some/every/map/filter/reduce的区别// 1. foreach:就是 ...

  4. map/set/object/array对比

    map () {//数据结构横向对比, 增,查,改,删let map = new Map()let array = []//增map.set('t',1)array.push({t:1})consol ...

  5. List(Map(String, Object))转为Fastjson JSONArray

    原始的 List<Map<String, Object>> test_list_map 内容如下: [{path=hdfs://manager:9000/testDir/1.t ...

  6. java实现map和object互转

    maven依赖 <dependency><groupId>commons-beanutils</groupId><artifactId>commons- ...

  7. 字节一面 —— List 和 Map、Set 的区别

    马上就要到金三银四佳季了,是找工作的好时候,小伙伴们一定要把握好时机,找到心仪的高薪工作.找工作就少不了面试,那我们从现在开始,多刷刷面试题,查缺补漏!!! 目录 ⭐常见的数据结构⭐ ⭐集合和数组的区 ...

  8. python lambda map reduce_简单了解python filter、map、reduce的区别

    这篇文章主要介绍了简单了解python filter.map.reduce的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python中有一些 ...

  9. Hadoop的Mapreduce中Mapper的key和Map的key的区别

    Hadoop的Mapreduce中Mapper的key和Map的key的区别 问题:我们知道Mapreduce 是以键值对的方式进行输入输出的,分为Mapper <k,v,k,v>和Red ...

最新文章

  1. python中绝对路径的区别,理解Python中的绝对路径和相对路径
  2. UA STAT675 统计计算I 随机数生成1 随机数生成器的一般理论
  3. C++ 学习笔记----类篇
  4. 由浅到深理解ROS(9)- 几个基本概念的理解 坐标系 包
  5. 中关村win11 32位全新官方版镜像v2021.07
  6. 如何学习机器学习、看待算法竞赛?粉丝精选留言
  7. LeetCode 142. 环形链表 II(Linked List Cycle II)
  8. 两种“新型”的javaweb后门(jspx和Java Logger)
  9. IOS改地区:美国、新西兰等等
  10. 因接外包坐牢456天,我都经历了什么?
  11. openg 通用扫描画线算法
  12. Android dex2oat 导致编译失败:ERROR: Dex2oat failed to compile a boot image
  13. AD软件解决 Unknown Pin 和Failed to add class member 问题
  14. 计算机管理创建超级用户,win10系统怎么创建超级管理员账户
  15. jqueryCutDown.js结合moment.js倒计时整理,直接copy可用,别忘了引入jquery
  16. sh文件加密解密gzexe(Cannot decompress $0)
  17. 如何判断外汇平台是否整个?MT4外汇投资靠谱吗?
  18. PS用橡皮檫檫除图形与背景颜色一样的方法
  19. 上网行为安全之防火墙端口映射及应用
  20. 这58张图片,能让你笑出八块腹肌!

热门文章

  1. Linux内存初始化(C语言部分)
  2. ICLR 2017 | GAN Missing Modes 和 GAN
  3. 重塑世界的区块链技术你必须要懂得
  4. JZOJ 3453【NOIP2013中秋节模拟】连通块
  5. qq地区采集_用户诉QQ浏览器违法收集个人隐私,法院裁定腾讯立即停止相关行为...
  6. NOIP信息奥赛--1995“同创杯”初中复赛题题解(四)
  7. SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机)【两种做法】
  8. matlab制作小工具,Matlab有用的小工具小技巧
  9. java rabbitmq 绑定_RabbitMQ:交换,队列和绑定 - 谁设置了什么?
  10. nginx动静分离配置_nginx动静分离实战