Map

Map 객체는 키-값 쌍을 저장하며 각 쌍의 삽입 순서도 기억하는 콜렉션입니다. 아무 값(객체와 원시 값)이라도 키와 값으로 사용할 수 있습니다.

설명

Map 객체는 요소의 삽입 순서대로 원소를 순회합니다. for...of 반복문은 각 순회에서 [key, value]로 이루어진 배열을 반환합니다.

키 동일성

  • 키 동일성은 sameValueZero 알고리즘에 기반합니다.
  • NaN !== NaN이지만, 그럼에도 NaNNaN과 일치한다고 간주하며, 다른 모든 값은 === 연산자의 결과를 따릅니다.
  • 현 ECMAScript 명세는 -0+0을 같은 값으로 처리하지만 초기 명세에서는 그렇지 않았습니다. 브라우저 호환성의 "Key equality for -0 and 0"을 참고하세요.

ObjectMap 비교

Object는 값에 키를 할당할 수 있고, 그 키로 값을 얻을 수 있고, 키를 삭제할 수 있으며 어떤 키에 값이 존재하는지 확인할 수 있다는 점에서 Map과 유사합니다. 이런 이유에 더해, 이전에는 내장된 대체제가 없었기 때문에, ObjectMap 대신 사용하곤 했습니다.

그러나 어떤 상황에선, Map을 선호해야 할 몇 가지 중요한 차이점이 있습니다.

Map Object
의도치 않은 키 Map은 명시적으로 제공한 키 외에는 어떤 키도 가지지 않습니다.

Object는 프로토타입을 가지므로 기본 키가 존재할 수 있습니다. 주의하지 않으면 직접 제공한 키와 충돌할 수도 있습니다.

참고: ES5부터, 프로토타입으로 인한 키 충돌은 Object.create(null)로 해결할 수 있지만, 실제로 쓰이는 경우는 적습니다.

키 자료형 Map의 키는 함수, 객체 등을 포함한 모든 값이 가능합니다. Object의 키는 반드시 String 또는 Symbol이어야 합니다.
키 순서

Map의 키는 정렬됩니다. 따라서 Map의 순회는 삽입순으로 이뤄집니다.

Object의 키는 정렬되지 않습니다.

참고: ECMAScript 201 이후로, 객체도 문자열과 Symbol 키의 생성 순서를 유지합니다. ECMEScript 2015 명세를 준수하는 JavaScript 엔진에서 문자열 키만 가진 객체를 순회하면 삽입 순을 따라갑니다.

크기 Map의 항목 수는 size 속성을 통해 쉽게 알아낼 수 있습니다. Object의 항목 수는 직접 알아내야 합니다.
순회 Map순회 가능하므로, 바로 순회할 수 있습니다. Object를 순회하려면 먼저 모든 키를 알아낸 후, 그 키의 배열을 순회해야 합니다.
성능 잦은 키-값 쌍의 추가와 제거에서 더 좋은 성능을 보입니다. 잦은 키-값 쌍의 추가와 제거를 위한 최적화가 없습니다.

생성자

Map()
새로운 Map 객체를 생성합니다.

속성

Map.length
값이 0인 속성입니다.
요소의 수는 Map.prototype.size로 알아낼 수 있습니다.
get Map[@@species]
파생 객체를 생성하는데 사용하는 생성자 함수입니다.
Map.prototype
Map 생성자의 프로토타입을 나타냅니다. 모든 Map 인스턴스에 속성을 추가할 수 있습니다.

Map 인스턴스

모든 Map 인스턴스는 Map.prototype을 상속합니다.

속성

Map.prototype.constructor
인스턴스의 프로토타입을 만드는 함수를 반환한다. 이것 Map 함수의 기본 값이다.
Map.prototype.size
Map 객체에 들어있는 key/value pair의 수를 반환한다.

메서드

Map.prototype.clear()
Map 객체의 모든 key/value pair를 제거한다.
Map.prototype.delete(key)
주어진 키(Key)와 해당되는 값(Value)를 제거하고 제거하기 전에 Map.prototype.has(key)가 반환했던 값을 반환한다. 그 후의 Map.prototype.has(key)는 false를 반환한다.
Map.prototype.entries()
Map 객체 안의 모든 요소들을 [key, value] 형태의 array 로 집어넣은 순서대로 가지고 있는 Iterator 객체를 반환한다.
Map.prototype.forEach(callbackFn[, thisArg])
Map 객체 안에 존재하는 각각의 key/value pair에 집어넣은 순서대로 callbackFn을 부른다. 만약 thisArg 매개변수가 제공되면, 이것이 각 callback의 this 값으로 사용된다.
Map.prototype.get(key)
주어진 키(Key)에 해당되는 값(value)을 반환하고, 만약 없으면 undefined를 반환한다.
Map.prototype.has(key)
Map 객체 안에 주어진 key/value pair가 있는지 검사하고 Boolean 값을 반환한다.
Map.prototype.keys()
Map 객체 안의 모든 키(Key)들을 집어넣은 순서대로 가지고 있는 Iterator 객체를 반환한다.
Map.prototype.set(key, value)
Map 객체에 주어진 키(Key)에 값(Value)를 집어넣고, Map 객체를 반환한다.
Map.prototype.values()
Map 객체 안의 모든 (Value)들을 집어넣은 순서대로 가지고 있는 Iterator 객체를 반환한다.
Map.prototype[@@iterator]()
Map 객체 안의 모든 요소들을 [key, value] 형태의 array 로 집어넣은 순서대로 가지고 있는 Iterator 객체를 반환한다.

예제

Map 객체 사용하기

let myMap = new Map()

let keyString = '문자열'
let keyObj    = {}
let keyFunc   = function() {}

// 값 설정
myMap.set(keyString, "'문자열'과 관련된 값")
myMap.set(keyObj, 'keyObj와 관련된 값')
myMap.set(keyFunc, 'keyFunc와 관련된 값')

myMap.size              // 3

// getting the values
myMap.get(keyString)    // "'문자열'과 관련된 값"
myMap.get(keyObj)       // "keyObj와 관련된 값"
myMap.get(keyFunc)      // "keyFunc와 관련된 값"

myMap.get('문자열')    // "'문자열'과 관련된 값"
                         // keyString === '문자열'이기 때문
myMap.get({})            // undefined, keyObj !== {}
myMap.get(function() {}) // undefined, keyFunc !== function () {}

Map의 키로 NaN 사용하기

NaN도 키로서 사용할 수 있습니다. 모든 NaN은 자기 자신과 동일하지 않지만(NaN !== NaN), NaN을 서로 구분할 수도 없기 때문에 아래 예제도 잘 동작합니다.

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"

for..ofMap 순회하기

Mapfor..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

forEach()Map 순회하기

MapforEach() 메서드로 순회할 수 있습니다.

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

Array 객체와의 관계

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"]

명세

Specification
ECMAScript Latest Draft (ECMA-262)
The definition of 'Map' in that specification.

브라우저 호환성

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
MapChrome Full support 38Edge Full support 12Firefox Full support 13IE Full support 11Opera Full support 25Safari Full support 8WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 14Opera Android Full support 25Safari iOS Full support 8Samsung Internet Android Full support 3.0nodejs Full support 0.12
Full support 0.12
Full support 0.10
Disabled
Disabled From version 0.10: this feature is behind the --harmony runtime flag.
Map() constructorChrome Full support 38Edge Full support 12Firefox Full support 13IE Full support 11Opera Full support 25Safari Full support 8WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 14Opera Android Full support 25Safari iOS Full support 8Samsung Internet Android Full support 3.0nodejs Full support Yes
clearChrome Full support 38Edge Full support 12Firefox Full support 19IE Full support 11Opera Full support 25Safari Full support 8WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 19Opera Android Full support 25Safari iOS Full support 8Samsung Internet Android Full support 3.0nodejs Full support 0.12
deleteChrome Full support 38Edge Full support 12Firefox Full support 13IE Full support 11Opera Full support 25Safari Full support 8WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 14Opera Android Full support 25Safari iOS Full support 8Samsung Internet Android Full support 3.0nodejs Full support 0.12
Full support 0.12
Full support 0.10
Disabled
Disabled From version 0.10: this feature is behind the --harmony runtime flag.
entriesChrome Full support 38Edge Full support 12Firefox Full support 20IE No support NoOpera Full support 25Safari Full support 8WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 20Opera Android Full support 25Safari iOS Full support 8Samsung Internet Android Full support 3.0nodejs Full support 0.12
forEachChrome Full support 38Edge Full support 12Firefox Full support 25IE Full support 11Opera Full support 25Safari Full support 8WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 25Opera Android Full support 25Safari iOS Full support 8Samsung Internet Android Full support 3.0nodejs Full support 0.12
getChrome Full support 38Edge Full support 12Firefox Full support 13IE Full support 11Opera Full support 25Safari Full support 8WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 14Opera Android Full support 25Safari iOS Full support 8Samsung Internet Android Full support 3.0nodejs Full support Yes
hasChrome Full support 38Edge Full support 12Firefox Full support 13IE Full support 11Opera Full support 25Safari Full support 8WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 14Opera Android Full support 25Safari iOS Full support 8Samsung Internet Android Full support 3.0nodejs Full support Yes
Key equality for -0 and 0Chrome Full support 38Edge Full support 12Firefox Full support 29IE No support NoOpera Full support 25Safari Full support 9WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 29Opera Android Full support 25Safari iOS Full support 9Samsung Internet Android Full support 3.0nodejs Full support 4.0.0
keysChrome Full support 38Edge Full support 12Firefox Full support 20IE No support NoOpera Full support 25Safari Full support 8WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 20Opera Android Full support 25Safari iOS Full support 8Samsung Internet Android Full support 3.0nodejs Full support 0.12
setChrome Full support 38Edge Full support 12Firefox Full support 13IE Partial support 11
Notes
Partial support 11
Notes
Notes Returns 'undefined' instead of the 'Map' object.
Opera Full support 25Safari Full support 8WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 14Opera Android Full support 25Safari iOS Full support 8Samsung Internet Android Full support 3.0nodejs Full support Yes
sizeChrome Full support 38Edge Full support 12Firefox Full support 19
Notes
Full support 19
Notes
Notes 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 Full support 11Opera Full support 25Safari Full support 8WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 19
Notes
Full support 19
Notes
Notes 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 Full support 25Safari iOS Full support 8Samsung Internet Android Full support 3.0nodejs Full support 0.12
valuesChrome Full support 38Edge Full support 12Firefox Full support 20IE No support NoOpera Full support 25Safari Full support 8WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 20Opera Android Full support 25Safari iOS Full support 8Samsung Internet Android Full support 3.0nodejs Full support 0.12
@@iteratorChrome Full support 43Edge Full support 12Firefox Full support 36
Full support 36
No support 27 — 36
Notes Alternate Name
Notes A placeholder property named @@iterator is used.
Alternate Name Uses the non-standard name: @@iterator
No support 17 — 27
Notes Alternate Name
Notes A placeholder property named iterator is used.
Alternate Name Uses the non-standard name: iterator
IE No support NoOpera Full support 30Safari Full support 10WebView Android Full support 43Chrome Android Full support 43Firefox Android Full support 36
Full support 36
No support 27 — 36
Notes Alternate Name
Notes A placeholder property named @@iterator is used.
Alternate Name Uses the non-standard name: @@iterator
No support 17 — 27
Notes Alternate Name
Notes A placeholder property named iterator is used.
Alternate Name Uses the non-standard name: iterator
Opera Android Full support 30Safari iOS Full support 10Samsung Internet Android Full support 4.0nodejs Full support 0.12
@@speciesChrome Full support 51Edge Full support 13Firefox Full support 41IE No support NoOpera Full support 38Safari Full support 10WebView Android Full support 51Chrome Android Full support 51Firefox Android Full support 41Opera Android Full support 41Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.5.0
Full support 6.5.0
Full support 6.0.0
Disabled
Disabled From version 6.0.0: this feature is behind the --harmony runtime flag.
@@toStringTagChrome Full support 44Edge Full support 79Firefox Full support 51IE No support NoOpera No support NoSafari No support NoWebView Android Full support 44Chrome Android Full support 44Firefox Android Full support 51Opera Android No support NoSafari iOS No support NoSamsung Internet Android Full support 4.0nodejs No support No

Legend

Full support  
Full support
Partial support  
Partial support
No support  
No support
See implementation notes.
See implementation notes.
User must explicitly enable this feature.
User must explicitly enable this feature.
Uses a non-standard name.
Uses a non-standard name.

같이 보기