diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/index.md b/files/zh-cn/web/javascript/reference/global_objects/map/index.md index 97b0956ed213b0..dacdb17bffec29 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/map/index.md +++ b/files/zh-cn/web/javascript/reference/global_objects/map/index.md @@ -5,13 +5,13 @@ slug: Web/JavaScript/Reference/Global_Objects/Map {{JSRef}} -**`Map`** 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者{{Glossary("Primitive", "基本类型")}})都可以作为一个键或一个值。 +**`Map`** 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者{{Glossary("Primitive", "原始值")}})都可以作为键或值。 {{EmbedInteractiveExample("pages/js/map.html", "taller")}} ## 描述 -`Map` 对象是键值对的集合。`Map` 中的一个键**只能出现一次**;它在 `Map` 的集合中是独一无二的。`Map` 对象按键值对迭代——一个 {{jsxref("Statements/for...of", "for...of")}} 循环在每次迭代后会返回一个形式为 `[key,value]` 的数组。迭代按*插入顺序*进行,即键值对按 [`set()`](/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map/set) 方法首次插入到集合中的顺序(也就是说,当调用 `set()` 时,map 中没有具有相同值的键)进行迭代。 +`Map` 对象是键值对的集合。`Map` 中的一个键**只能出现一次**;它在 `Map` 的集合中是独一无二的。`Map` 对象按键值对迭代——一个 {{jsxref("Statements/for...of", "for...of")}} 循环在每次迭代后会返回一个形式为 `[key, value]` 的数组。迭代按*插入顺序*进行,即键值对按 [`set()`](/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map/set) 方法首次插入到集合中的顺序(也就是说,当调用 `set()` 时,map 中没有具有相同值的键)进行迭代。 规范要求 map 实现“平均访问时间与集合中的元素数量呈次线性关系”。因此,它可以在内部表示为哈希表(使用 O(1) 查找)、搜索树(使用 O(log(N)) 查找)或任何其他数据结构,只要复杂度小于 O(N)。 @@ -36,95 +36,107 @@ slug: Web/JavaScript/Reference/Global_Objects/Map
Map
默认情况不包含任何键。只包含显式插入的键。一个 Object
有一个原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
Map
默认不包含任何键。它只包含显式存入的键值对。
+
+ Object
有原型,因此它包含默认的键,如果不小心的话,它们可能会与你自己的键相冲突。
+
备注:虽然可以用 {{jsxref("Object.create", "Object.create(null)")}} 来创建一个没有原型的对象,但是这种用法不太常见。
++ 备注:这可以通过使用 {{jsxref("Object.create", "Object.create(null)")}} 来绕过,但很少这样做。 +
Map
可以安全地与用户提供的键值一起使用。
+
+ 在 Object
上设置用户提供的键值对可能会允许攻击者覆盖对象的原型,这可能会导致对象注入攻击。就像意外的键问题一样,这也可以通过使用 null
原型对象来缓解。
+
Map
的键可以是任意值,包括函数、对象或任意基本类型。Object
的键必须是一个 {{jsxref("String")}} 或是 {{jsxref("Symbol")}}。Map
的键可以为任何值(包括函数、对象或任何原始值)。
+ Object
的键必须为 {{jsxref("String")}} 或 {{jsxref("Symbol")}}。
+ Map
中的键是有序的。因此,当迭代的时候,一个 Map
对象以插入的顺序返回键值。
+ Map
中的键以简单、直接的方式排序:Map
对象按照插入的顺序迭代条目、键和值。
+
虽然 Object
的键目前是有序的,但并不总是这样,而且这个顺序是复杂的。因此,最好不要依赖属性的顺序。
自 ECMAScript 2015 规范以来,对象的属性被定义为是有序的;ECMAScript 2020 则额外定义了继承属性的顺序。参见 OrdinaryOwnPropertyKeys
- 和
- EnumerateObjectProperties 抽象规范说明。但是,请注意没有可以迭代对象所有属性的机制,每一种机制只包含了属性的不同子集。({{jsxref("Statements/for...in","for-in")}}
- 仅包含了以字符串为键的属性;{{jsxref("Object.keys")}}
- 仅包含了对象自身的、可枚举的、以字符串为键的属性;{{jsxref("Object.getOwnPropertyNames")}}
- 包含了所有以字符串为键的属性,即使是不可枚举的;{{jsxref("Object.getOwnPropertySymbols")}}
- 与前者类似,但其包含的是以 Symbol
为键的属性,等等。)
+
+ 尽管现在普通的 Object
的键是有序的,但情况并非总是如此,并且其排序比较复杂的。因此,最好不要依赖属性的顺序。
+
+ 该顺序最初仅在 ECMAScript 2015 中为自有属性定义;ECMAScript 2020 还定义了继承属性的顺序。但请注意,没有单一机制可以迭代对象的所有属性;各种机制各自包含不同的属性子集。({{jsxref("Statements/for...in", "for-in")}} 仅包含可枚举的字符串键属性;{{jsxref("Object.keys")}} 仅包含可枚举的自有字符串键属性;{{jsxref("Object.getOwnPropertyNames")}} 包括自有的字符串键属性,即使是不可枚举的;{{jsxref("Object.getOwnPropertySymbols")}} 仅对 Symbol
键属性执行相同的操作,等等。)
Map
的键值对个数可以轻易地通过 {{jsxref("Map.prototype.size", "size")}} 属性获取。Object
的键值对个数只能手动计算。大小
Map
中的项目数量很容易从其 {{jsxref("Map.prototype.size", "size")}} 属性中获得。
+ Object
中的项目数量通常更麻烦,效率也较低。一种常见的方法是通过获取 {{jsxref("Object.keys()")}} 返回的数组的{{jsxref("Array/length", "长度", "", 1)}}。
+ Map
是 可迭代的 的,所以可以直接被迭代。Object
没有实现 迭代协议,所以使用 JavaSctipt 的 for...of 表达式并不能直接迭代对象。
备注:
-Object.keys
或 Object.entries
。
- Map
是可迭代对象,所以它可以直接迭代。
+
+ Object
没有实现迭代协议,因此对象默认情况下不能直接通过 JavaScript 的 for...of 语句进行迭代。
+
备注:
+Object.keys
或 Object.entries
来获取一个对象的可迭代对象。
+ 在频繁增删键值对的场景下表现更好。
+在涉及频繁添加和删除键值对的场景中表现更好。
在频繁添加和删除键值对的场景下未作出优化。
+未针对频繁添加和删除键值对进行优化。
没有元素的序列化和解析的支持。
-(但是你可以使用携带 replacer 参数的 {{jsxref("JSON.stringify()")}} 创建一个自己的对 Map
的序列化和解析支持。参见 Stack Overflow 上的提问:How do you JSON.stringify an ES6 Map?)
没有对序列化或解析的原生支持。
+
+ (但你可以通过使用 {{jsxref("JSON.stringify()")}} 及其 replacer 参数和 {{jsxref("JSON.parse()")}} 及其 reviver 参数来为 Map
构建自己的序列化和解析支持。参见 Stack Overflow 问题 How do you JSON.stringify an ES6 Map?)。
+
原生的由 {{jsxref("Object")}} 到 JSON 的序列化支持,使用 {{jsxref("JSON.stringify()")}}。
-原生的由 JSON 到 {{jsxref("Object")}} 的解析支持,使用 {{jsxref("JSON.parse()")}}。
+原生支持使用 {{jsxref("JSON.stringify()")}} 序列化 {{jsxref("Object")}} 到 JSON。
+原生支持使用 {{jsxref("JSON.parse()")}} 解析 JSON 为 {{jsxref("Object")}}。