Map

현재 번역은 완벽하지 않습니다. 한국어로 문서 번역에 동참해주세요.

Map 객체는 간단한 key/value map 이다. 어떠한 value ( 객체들과 primitive values 둘 모두, 키 또는 값으로서 사용될 수 있다.

Syntax

new Map([iterable])

Parameters

iterable
Iterable 은 배열이거나, element 들이 key-value 쌍(2-element Arrays)을 이루는 다른 iterable 객체이다. 각 key-value 쌍은 새로운 Map 에 추가된다. nullundefined 로서 취급된다.

Description

Map 객체는 삽입 순서대로 그것의 element 들을 순회한다. — for...of loop 는 각 반복 동안 [key, value] 배열을 반환한다.

주의해야할 점은, Object의 Map 즉 통상적인 Object를 값으로 가진 Map은 값으로 저장된 Object의 property의 순서를 보장하지 않으며 임의로 저장하게 된다.

키(Key) 동일성

키(Key) 동일성은 "same-value" 알고리즘에 기초한다: NaNNaN과 동일한 것으로 간주되며(비록 NaN !== NaN 일지라도), 모든 다른 값들은 === 연산자의 의미를 따라 동일하다고 간주된다. 초기 버젼의 ECMAScript 6 draft에서는 -0과 +0이 다른 것으로 간주되었다. (비록 -0 === +0 일지라도) 이것은 후기 버젼에서 변경되었고, Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26) (bug 952870)와 recent nightly Chrome에 적용되었다.

Objects와 maps의 비교

Objects는 값을 키로 저장하고 불러올 수 있다는 점, 키를 삭제할 수 있다는 점, 그리고 어떠한 값이 저장되어있는지 확인할 수 있다는 점에서 Maps와 유사하다.  이러한 이유때문에(그리고 Built-in된 대체제가 없었던 이유로), 역사적으로 Objects는 Maps로 사용되어왔다. 그러나 Map을 사용하는 것이 Objects를 사용하는 것보다 더 나은 몇가지 중요한 차이점이 있다:

  • Object는 프로토타입을 가지고 있다. 그렇기 때문에 map(역자 주: Object를 의미)에 의도치않은 default key가 있다. 이것은 ES5 이래로 map = Object.create(null)으로 회피할 수 있지만, 거의 사용되지 않았다.
  • Object의 키는 Strings 과 Symbols 밖에 될 수 없으나, Map에서는 어떤 값도 가능하다.
  • Object에서는 그 크기를 계속해서 추적해야만 하지만 Map에서는 손쉽게 크기를 얻을 수 있다(역자 주: map.size)

하지만 이것이 모든 곳에서 Maps를 사용해야 한다는 의미는 아니며, Objects는 여전히 대부분의 경우에 사용할 수 있다. Map 인스턴스는 collections의 경우에만 유용하며(역자 주: OOP에서의 building block인 인스턴스가 아닌 단순한 데이터의 집합이라는 의미로 보임), 그러한 경우에는 기존에 사용되던 Object를 Map으로 대체하는 것을 고려해볼 필요가 있다. Objects는 필드와 메소드를 가진 records로써 사용되어야 한다. 만약 아직 무엇을 사용해야 할지 확신이 서지 않는다면, 다음의 질문을 해보도록 하자.

  • 통상적으로 키(Key)는 런타임까지 알 수 없으며, 유동적으로 그것들을 찾아야 하는가?
  • 모든 값(Value)는 동일한 타입을 가지고 있으며, 상호 변환이 가능하도록 사용되는가? (원문: Do all values have the same type, and can be used interchangeably?)
  • 문자열이 아닌 키(Key)가 필요한가?
  • 키-값 짝이 때때로 추가되거나 삭제되는가?
  • 자주, 쉽게 변하는 임의의 양의 키-값 짝이 있는가?
  • 데이터가 Iterated 되어야 하는가?(원문: Is the collection iterated?)

위의 질문들은 모두 Map을 collection으로 사용하기에 적절하다는 신호이다. 이와 반대로 고정된 양의 키(Key)가 있거나, 개별적으로 키-값의 짝들을 조작하거나 혹은 각각의 짝을 용도에 따라 구분해야한다면, Object를 사용하는 것이 적절할 것이다.

Properties

Map.length
length 속성의 값은 0 이다.
get Map[@@species]
파생된 객체를 만들기 위해 사용되는 constructor 함수이다.
Map.prototype
Map constructor의 프로토타입을 나타낸다. 모든 Map instance에 property를 추가할 수 있게 해준다.

Map instances

모든 Map instance 들은 Map.prototype 를 상속한다.

Properties

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

Methods

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 객체 사용하기

var myMap = new Map();

var keyString = "a string",
    keyObj = {},
    keyFunc = function () {};

// 값 저장하기
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

// 값 불러오기
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 () {}

Map의 키(Key)로 NaN 사용하기

NaN은 키(Key)로써도 사용 가능하다. 비록 모든 NaN이 그 자신과 동일하지 않지만(NaN !== NaN), NaN은 구분이 불가능하기 때문에(역자 주: 동일한 것으로 간주) 아래의 예시는 동작한다:

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로 Maps 순회하기

Map 들은 for..of loop 를 사용하여 순회할 수 있다. :

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
// 0 = zero
// 1 = one

for (var key of myMap.keys()) {
  console.log(key);
}
// 0
// 1

for (var value of myMap.values()) {
  console.log(value);
}
// zero
// one

for (var [key, value] of myMap.entries()) {
  console.log(key + " = " + value);
}
// 0 = zero
// 1 = one

forEach()로 Maps 순회하기

Map 들은 forEach() 메소드의 사용으로 순회할 수 있다. :

myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
});
// 2개의 로그를 출력한다; 첫 번째는 "0 = zero"이며 두 번째는 "1 = one"이다

Array 객체와의 관계

var kvArray = [["key1", "value1"], ["key2", "value2"]];

// 2D Array를 일반적인 Map constructor를 이용하여 Map 인스턴스를 만든다.
var myMap = new Map(kvArray);

myMap.get("key1"); // returns "value1"

// Spread 연사자를 이용하여 map을 2D key-value Array로 변환한다.
console.log(uneval([...myMap])); // Will show you exactly the same Array as kvArray

// 혹은 keys나 values iterator에 spread operator를 사용하여 키나 값들의 Array를 얻는다.
console.log(uneval([...myMap.keys()])); // Will show ["key1", "key2"]

Specifications

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Map' in that specification.
Standard Initial definition.
ECMAScript Latest Draft (ECMA-262)
The definition of 'Map' in that specification.
Draft  

Browser compatibility

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support

38 [1]

13 (13) 11 25 7.1
Constructor argument: new Map(iterable) 38 13 (13) No support 25 No support
iterable 38 17 (17) No support 25 7.1
Map.clear() 31
38
19 (19) 11 25 7.1
Map.keys(), Map.values(), Map.entries() 37
38
20 (20) No support 25 7.1
Map.forEach() 36
38
25 (25) 11 25 7.1
Key equality for -0 and 0 34
38
29 (29) No support 25 No support
Constructor argument: new Map(null) (Yes) 37 (37) ? ? ?
Monkey-patched set() in Constructor (Yes) 37 (37) ? ? ?
Map[@@species] ? 41 (41) ? ? ?
Map() without new throws ? 42 (42) ? ? ?
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support No support 38 [1] 13.0 (13) No support No support 8
Constructor argument: new Map(iterable) No support 38 13.0 (13) No support No support No support
iterable No support No support 17.0 (17) No support No support 8
Map.clear() No support 31
38
19.0 (19) No support No support 8
Map.keys(), Map.values(), Map.entries() No support 37
38
20.0 (20) No support No support 8
Map.forEach() No support 36
38
25.0 (25) No support No support 8
Key equality for -0 and 0 No support 34
38
29.0 (29) No support No support No support
Constructor argument: new Map(null) ? (Yes) 37.0 (37) ? ? ?
Monkey-patched set() in Constructor ? (Yes) 37.0 (37) ? ? ?
Map[@@species] ? ? 41.0 (41) ? ? ?
Map() without new throws ? ? 42.0 (42) ? ? ?

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

See also

문서 태그 및 공헌자

태그: 
 이 페이지의 공헌자: echo304, dragmove
 최종 변경: echo304,