Map object holds key-value pairs and remembers the original insertion order of the keys. Any value (both objects and 原语值 ) may be used as either a key or a value.

描述

Map object iterates its elements in insertion order — a for...of loop returns an array of [ key , value ] for each iteration.

键相等

  • Key equality is based on the sameValueZero algorithm.
  • NaN is considered the same as NaN (even though NaN !== NaN ) and all other values are considered equal according to the semantics of the === operator.
  • In the current ECMAScript specification, -0 and +0 are considered equal, although this was not so in earlier drafts. See "Value equality for -0 and 0" 浏览器兼容性 table for details.

对象 vs 映射

Object 类似于 Map —both let you set keys to values, retrieve those values, delete keys, and detect whether something is stored at a key. For this reason (and because there were no built-in alternatives), Object s have been used as Map s historically.

However, there are important differences that make Map preferable in certain cases:

Map Object
Accidental Keys A Map does not contain any keys by default. It only contains what is explicitly put into it. An Object has a prototype, so it contains default keys that could collide with your own keys if you're not careful.

注意: As of ES5, this can be bypassed by using Object.create(null) , but this is seldom done.

Key Types A Map 's keys can be any value (including functions, objects, or any primitive). The keys of an Object must be either a String Symbol .
Key Order The keys in Map are ordered. Thus, when iterating over it, a Map object returns keys in order of insertion. The keys of an Object are not ordered.

注意: Since ECMAScript 2015, objects do preserve creation order for string and Symbol keys. In JavaScript engines that comply with the ECMAScript 2015 spec, iterating over an object with only string keys will yield the keys in order of insertion.

Size The number of items in a Map is easily retrieved from its size 特性。 The number of items in an Object must be determined manually.
迭代 A Map iterable , so it can be directly iterated. Iterating over an Object requires obtaining its keys in some fashion and iterating over them.
Performance Performs better in scenarios involving frequent additions and removals of key-value pairs. Not optimized for frequent additions and removals of key-value pairs.

设置对象特性

Setting Object properties works for Map objects as well, and can cause considerable confusion.

Therefore, this appears to work in a way:

let wrongMap = new Map()
wrongMap['bla'] = 'blaa'
wrongMap['bla2'] = 'blaaa2'
console.log(wrongMap)  // Map { bla: 'blaa', bla2: 'blaaa2' }
					

But that way of setting a property does not interact with the Map data structure. It uses the feature of the generic object. The value of 'bla' is not stored in the Map for queries. Other operations on the data fail:

wrongMap.has('bla')    // false
wrongMap.delete('bla') // false
console.log(wrongMap)  // Map { bla: 'blaa', bla2: 'blaaa2' }
					

The correct usage for storing data in the Map is through the set( key , value ) 方法。

let contacts = new Map()
contacts.set('Jessie', {phone: "213-555-1234", address: "123 N 1st Ave"})
contacts.has('Jessie') // true
contacts.get('Hilary') // undefined
contacts.set('Hilary', {phone: "617-555-4321", address: "321 S 2nd St"})
contacts.get('Jessie') // {phone: "213-555-1234", address: "123 N 1st Ave"}
contacts.delete('Raymond') // false
contacts.delete('Jessie') // true
console.log(contacts.size) // 1
					

构造函数

Map()
创建新的 Map 对象。

静态特性

get Map[@@species]

The constructor function that is used to create derived objects.

实例特性

Map.prototype.size
Returns the number of key/value pairs in the Map 对象。

实例方法

Map.prototype.clear()
Removes all key-value pairs from the Map 对象。
Map.prototype.delete( key )
返回 true if an element in the Map object existed and has been removed, or false if the element does not exist. Map.prototype.has( key ) will return false afterwards.
Map.prototype.get( key )
Returns the value associated to the key ,或 undefined 若没有。
Map.prototype.has( key )
Returns a boolean asserting whether a value has been associated to the key Map object or not.
Map.prototype.set( key , value )
设置 value key Map object. Returns the Map 对象。

迭代方法

Map.prototype[@@iterator]()
返回新的 Iterator object that contains an array of [ key , value ] for each element in the Map object in insertion order.
Map.prototype.keys()
返回新的 Iterator object that contains the keys for each element in the Map object in insertion order.
Map.prototype.values()
返回新的 Iterator object that contains the for each element in the Map object in insertion order.
Map.prototype.entries()
返回新的 Iterator object that contains an array of [ key , value ] for each element in the Map object in insertion order.
Map.prototype.forEach( callbackFn [, thisArg ])
调用 callbackFn once for each key-value pair present in the Map object, in insertion order. If a thisArg parameter is provided to forEach , it will be used as the this value for each callback.

范例

使用 Map 对象

let myMap = new Map()
let keyString = 'a string'
let keyObj    = {}
let keyFunc   = function() {}
// setting the values
myMap.set(keyString, "value associated with 'a string'")
myMap.set(keyObj, 'value associated with keyObj')
myMap.set(keyFunc, 'value associated with keyFunc')
myMap.size              // 3
// getting the values
myMap.get(keyString)    // "value associated with 'a string'"
myMap.get(keyObj)       // "value associated with keyObj"
myMap.get(keyFunc)      // "value associated with keyFunc"
myMap.get('a string')    // "value associated with 'a string'"
                         // because keyString === 'a string'
myMap.get({})            // undefined, because keyObj !== {}
myMap.get(function() {}) // undefined, because keyFunc !== function () {}
					

使用 NaN 作为 Map 键

NaN can also be used as a key. Even though every NaN is not equal to itself ( NaN !== NaN is true), the following example works because NaN s are indistinguishable from each other:

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

遍历 Map 采用 for..of

Maps can be iterated using a for..of 循环:

let myMap = new Map()
myMap.set(0, 'zero')
myMap.set(1, 'one')
for (let [key, value] of myMap) {
  console.log(key + ' = ' + value)
}
// 0 = zero
// 1 = one
for (let key of myMap.keys()) {
  console.log(key)
}
// 0
// 1
for (let value of myMap.values()) {
  console.log(value)
}
// zero
// one
for (let [key, value] of myMap.entries()) {
  console.log(key + ' = ' + value)
}
// 0 = zero
// 1 = one
					

遍历 Map 采用 forEach()

Maps can be iterated using the forEach() method:

myMap.forEach(function(value, key) {
  console.log(key + ' = ' + value)
})
// 0 = zero
// 1 = one
					

与数组对象的关系

let kvArray = [['key1', 'value1'], ['key2', 'value2']]
// Use the regular Map constructor to transform a 2D key-value Array into a map
let myMap = new Map(kvArray)
myMap.get('key1') // returns "value1"
// Use Array.from() to transform a map into a 2D key-value Array
console.log(Array.from(myMap)) // Will show you exactly the same Array as kvArray
// A succinct way to do the same, using the spread syntax
console.log([...myMap])
// Or use the keys() or values() iterators, and convert them to an array
console.log(Array.from(myMap.keys())) // ["key1", "key2"]
					

克隆和合并 Map

就像 Array s, Map s can be cloned:

let original = new Map([
  [1, 'one']
])
let clone = new Map(original)
console.log(clone.get(1))       // one
console.log(original === clone) // false (useful for shallow comparison)
					

Important: Keep in mind that the data itself is not cloned.

Maps can be merged, maintaining key uniqueness:

let first = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
])
let second = new Map([
  [1, 'uno'],
  [2, 'dos']
])
// Merge two maps. The last repeated key wins.
// Spread operator essentially converts a Map to an Array
let merged = new Map([...first, ...second])
console.log(merged.get(1)) // uno
console.log(merged.get(2)) // dos
console.log(merged.get(3)) // three
					

Maps can be merged with Arrays, too:

let first = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
])
let second = new Map([
  [1, 'uno'],
  [2, 'dos']
])
// Merge maps with an array. The last repeated key wins.
let merged = new Map([...first, ...second, [1, 'eins']])
console.log(merged.get(1)) // eins
console.log(merged.get(2)) // dos
console.log(merged.get(3)) // three
					

规范

规范
ECMAScript (ECMA-262)
在该规范中的 Map 定义。

浏览器兼容性

The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request. 更新 GitHub 上的兼容性数据
Desktop Mobile Server
Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Firefox for Android Opera for Android Safari on iOS Samsung Internet Node.js
Map Chrome 38 Edge 12 Firefox 13 IE 11 Opera 25 Safari 8 WebView Android 38 Chrome Android 38 Firefox Android 14 Opera Android 25 Safari iOS 8 Samsung Internet Android 3.0 nodejs 0.12
0.12
0.10 Disabled
Disabled From version 0.10: this feature is behind the --harmony runtime flag.
Map() 构造函数 Chrome 38 Edge 12 Firefox 13 IE 11 Opera 25 Safari 8 WebView Android 38 Chrome Android 38 Firefox Android 14 Opera Android 25 Safari iOS 8 Samsung Internet Android 3.0 nodejs 0.12
0.12
0.10 Disabled
Disabled From version 0.10: this feature is behind the --harmony runtime flag.
clear Chrome 38 Edge 12 Firefox 19 IE 11 Opera 25 Safari 8 WebView Android 38 Chrome Android 38 Firefox Android 19 Opera Android 25 Safari iOS 8 Samsung Internet Android 3.0 nodejs 0.12
delete Chrome 38 Edge 12 Firefox 13 IE 11 Opera 25 Safari 8 WebView Android 38 Chrome Android 38 Firefox Android 14 Opera Android 25 Safari iOS 8 Samsung Internet Android 3.0 nodejs 0.12
0.12
0.10 Disabled
Disabled From version 0.10: this feature is behind the --harmony runtime flag.
entries Chrome 38 Edge 12 Firefox 20 IE No Opera 25 Safari 8 WebView Android 38 Chrome Android 38 Firefox Android 20 Opera Android 25 Safari iOS 8 Samsung Internet Android 3.0 nodejs 0.12
forEach Chrome 38 Edge 12 Firefox 25 IE 11 Opera 25 Safari 8 WebView Android 38 Chrome Android 38 Firefox Android 25 Opera Android 25 Safari iOS 8 Samsung Internet Android 3.0 nodejs 0.12
get Chrome 38 Edge 12 Firefox 13 IE 11 Opera 25 Safari 8 WebView Android 38 Chrome Android 38 Firefox Android 14 Opera Android 25 Safari iOS 8 Samsung Internet Android 3.0 nodejs 0.12
0.12
0.10 Disabled
Disabled From version 0.10: this feature is behind the --harmony runtime flag.
has Chrome 38 Edge 12 Firefox 13 IE 11 Opera 25 Safari 8 WebView Android 38 Chrome Android 38 Firefox Android 14 Opera Android 25 Safari iOS 8 Samsung Internet Android 3.0 nodejs 0.12
0.12
0.10 Disabled
Disabled From version 0.10: this feature is behind the --harmony runtime flag.
Key equality for -0 and 0 Chrome 38 Edge 12 Firefox 29 IE No Opera 25 Safari 9 WebView Android 38 Chrome Android 38 Firefox Android 29 Opera Android 25 Safari iOS 9 Samsung Internet Android 3.0 nodejs 4.0.0
keys Chrome 38 Edge 12 Firefox 20 IE No Opera 25 Safari 8 WebView Android 38 Chrome Android 38 Firefox Android 20 Opera Android 25 Safari iOS 8 Samsung Internet Android 3.0 nodejs 0.12
set Chrome 38 Edge 12 Firefox 13 IE 部分支持 11
部分支持 11
Returns 'undefined' instead of the 'Map' object.
Opera 25 Safari 8 WebView Android 38 Chrome Android 38 Firefox Android 14 Opera Android 25 Safari iOS 8 Samsung Internet Android 3.0 nodejs 0.12
0.12
0.10 Disabled
Disabled From version 0.10: this feature is behind the --harmony runtime flag.
size Chrome 38 Edge 12 Firefox 19
19
From Firefox 13 to Firefox 18, the size property was implemented as a Map.prototype.size() method, this has been changed to a property in later versions conform to the ECMAScript 2015 specification.
IE 11 Opera 25 Safari 8 WebView Android 38 Chrome Android 38 Firefox Android 19
19
From Firefox 13 to Firefox 18, the size property was implemented as a Map.prototype.size() method, this has been changed to a property in later versions conform to the ECMAScript 2015 specification.
Opera Android 25 Safari iOS 8 Samsung Internet Android 3.0 nodejs 0.12
Chrome 38 Edge 12 Firefox 20 IE No Opera 25 Safari 8 WebView Android 38 Chrome Android 38 Firefox Android 20 Opera Android 25 Safari iOS 8 Samsung Internet Android 3.0 nodejs 0.12
@@iterator Chrome 43 Edge 12 Firefox 36
36
不支持 27 — 36 Alternate Name
A placeholder property named @@iterator 被使用。
Alternate Name Uses the non-standard name: @@iterator
不支持 17 — 27 Alternate Name
A placeholder property named iterator 被使用。
Alternate Name Uses the non-standard name: iterator
IE No Opera 30 Safari 10 WebView Android 43 Chrome Android 43 Firefox Android 36
36
不支持 27 — 36 Alternate Name
A placeholder property named @@iterator 被使用。
Alternate Name Uses the non-standard name: @@iterator
不支持 17 — 27 Alternate Name
A placeholder property named iterator 被使用。
Alternate Name Uses the non-standard name: iterator
Opera Android 30 Safari iOS 10 Samsung Internet Android 4.0 nodejs 0.12
@@species Chrome 51 Edge 13 Firefox 41 IE No Opera 38 Safari 10 WebView Android 51 Chrome Android 51 Firefox Android 41 Opera Android 41 Safari iOS 10 Samsung Internet Android 5.0 nodejs 6.5.0
6.5.0
6.0.0 Disabled
Disabled From version 6.0.0: this feature is behind the --harmony runtime flag.
@@toStringTag Chrome 44 Edge 79 Firefox 51 IE No Opera No Safari No WebView Android 44 Chrome Android 44 Firefox Android 51 Opera Android No Safari iOS No Samsung Internet Android 4.0 nodejs 6.0.0

图例

完整支持

完整支持

部分支持

部分支持

不支持

不支持

见实现注意事项。

用户必须明确启用此特征。

用户必须明确启用此特征。

使用非标名称。

另请参阅

元数据

  • 最后修改: