企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] * * * * * >[info] `Map` 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。 ### 一. `Map` 和 普通对象 >[info] `Object` 和 `Map` 类似的一点是,它们都允许你按键存取一个值,都可以删除键,还可以检测一个键是否绑定了值。因此,一直以来,我们都把对象当成Map来使用。 现在有了 `Map` ,下面的区别解释了为什么使用 `Map` 更好点. ~~~ a. 一个对象通常都有自己的原型,所以一个对象总有一个 'prototype' 键。不过,从 ES5 开始可以使用 map = Object.create(null) 来创建一个没有原型的对象。 b. 一个对象的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值。 c. 你可以通过 size 属性很容易地得到一个 Map 的键值对个数,而对象的键值对个数只能手动确认。 ~~~ >[info] 但是这并不意味着你可以随意使用 `Map`,对象仍旧是最常用的。 `Map` 实例只适合用于集合 `(collections)`,你应当考虑修改你原来的代码——先前使用对象来处理集合的地方。对象应该用其字段和方法来作为记录的。 进一步确认是需要用什么: ~~~ a. 在运行之前 key 是否是未知的,是否需要动态地查询 key 呢? b. 是否所有的值都是统一类型,这些值可以互换么? c. 是否需要不是字符串类型的 key ? d. 键值对经常增加或者删除么? e. 是否有任意个且非常容易改变的键值对? f. 这个集合可以遍历么 (Is the collection iterated) ? ~~~ 假如以上全是“是”的话,那么你需要用 Map 来保存这个集。 相反,你有固定数目的键值对,独立操作它们,区分它们的用法,那么你需要的是对象。 * * * * * ### 二. 语法 #### 1. 构造 `Map` 对象 ~~~ <1>. 使用字面量构造,代码量少 var f1=function() {}, o1={}, s1=Symbol('rc'); var m1=new Map([ [1,'number'], ['name','wdd'], [f1,'a function.'], [o1,'a object'], [s1,'a Symbol'] ]); <2>. 调用方法,一个一个插入 var m2=new Map(); m2.set(key, value); ~~~ #### 4. `Map.prototype.size` 返回Map对象的键/值对的数量。 ![](https://box.kancloud.cn/85a4568e158512da5ffda38634117e30_278x335.png) #### 5. `Map.prototype.clear()` 移除Map对象的所有键/值对 。 ![](https://box.kancloud.cn/e7e9590ed1cb846b30e6244d28595493_233x354.png) #### 6. `Map.prototype.delete(key)` ~~~ 移除任何与键相关联的值,并且返回该值,该值在之前会被 Map.prototype.has(key) 返回为 true 。之后再调用 Map.prototype.has(key) 会返回 false 。 ~~~ ![](https://box.kancloud.cn/edd31c890ab659978f7e8a98ba44182d_166x175.png) #### 7. `Map.prototype.entries()` 返回一个新的 `Iterator` 对象,它按插入顺序包含了 `Map` 对象中每个元素的 `[key, value]` 数组。 #### 8. `Map.prototype.forEach(callbackFn[, thisArg])` ~~~ 按插入顺序,为 Map 对象里的每一键值对调用一次 callbackFn 函数。 如果为 forEach 提供了 thisArg,它将在每次回调中作为 this 值。 ~~~ #### 9. `Map.prototype.get(key)` 返回键对应的值,如果不存在,则返回 `undefined` 。 #### 10. `Map.prototype.has(key)` 返回一个布尔值,表示Map实例是否包含键对应的值。 ![](https://box.kancloud.cn/9817489ce63a7ec9c0705a7e3effa577_190x114.png) #### 11. `Map.prototype.keys()` 返回一个新的 `Iterator` 对象, 它按插入顺序包含了 `Map` 对象中每个元素的键 。 #### 12. `Map.prototype.set(key, value)` 设置 `Map` 对象中键的值。返回该 `Map` 对象。 #### 13. `Map.prototype.values()` 返回一个新的 `Iterator` 对象,它按插入顺序包含了 `Map` 对象中每个元素的值 。 #### 14. `Map.prototype[@@iterator]()` 返回一个新的 `Iterator` 对象,它按插入顺序包含了 `Map` 对象中每个元素的 `[key, value]` 数组。 #### 15. 键值为 `NaN` ~~~ map中的键值如果为 NaN ,那么只要一个值为 NaN ,就可以取出对应的值 (按标准,任何两个NaN都是不相等的);对于其他的键,一律以 === 规则来判断。 ~~~ ![](https://box.kancloud.cn/bd52af9ed246ad8f245a6d4d8580bca3_123x58.png) ~~~ var m2 = new Map(); m2.set(NaN, "not a number"); m2.get(NaN); // "not a number" var otherNaN = Number("foo"); m2.get(otherNaN); // "not a number" ~~~ ### 三. 遍历 `Map` #### 1. `of` 操作符 可见每一个元素都是一个含有两个值得数组,就和用字面量组装时候的一样。 ![](https://box.kancloud.cn/26122f3ae67cee09b5362edeadc5d3b9_311x204.png) #### 2. 只遍历键或值 ![](https://box.kancloud.cn/de4c80476c2dfb57fa062896d757522a_671x81.png) ![](https://box.kancloud.cn/7c6bbfa9cd174dc279f8f34bd3c7e81b_355x412.png) #### 3. `forEach` 方法 ![](https://box.kancloud.cn/96142018c5df34afff44618f71768ed3_374x202.png) >[danger] PS:`Map.keys(), Map.values(), Map.entries()` 这三个在 IE 11 中没有实现,其他浏览器没问题