JavaScript Map의 모든 것: Object가 있는데 왜 Map을 써야 할까?

작성일 :

JavaScript Map의 모든 것: Object가 있는데 왜 Map을 써야 할까?

JavaScript에서 데이터를 키-값 쌍으로 저장할 때 가장 먼저 떠오르는 것은 아마도 Object일 것입니다. 그러나 ES6에서 도입된 Map 객체는 다양한 상황에서 Object보다 더 나은 선택이 될 수 있습니다. 이번 글에서는 Map의 특성과 사용법을 살펴보고, Object와 비교하여 Map이 왜 유용한지를 다루겠습니다.

1. Map의 기본 개념

Map은 키-값 쌍을 저장하는 컬렉션입니다. Object와 비슷하게 동작하지만, 몇 가지 중요한 차이점이 있습니다. Map 객체는 각 키에 대해 하나의 값을 저장하며, 키는 모든 유형(primitive 값이나 객체)일 수 있습니다.

Map의 생성 및 기본 사용법

javascript
const map = new Map();
map.set("name", "Alice");
map.set("age", 25);
console.log(map.get("name")); // Alice
console.log(map.get("age")); // 25

위의 예제에서 볼 수 있듯이, Map을 생성하고 set 메서드를 사용하여 키-값 쌍을 추가합니다. get 메서드를 사용하여 값을 조회할 수 있습니다.

2. Object와 Map의 차이점

키 타입의 다양성

Object는 문자열 또는 심볼을 키로 가질 수 있지만, Map은 모든 유형의 값을 키로 가질 수 있습니다. 예를 들어, 숫자, 객체, 함수 등을 키로 사용할 수 있습니다.

javascript
const map = new Map();
map.set(1, "one");
map.set({}, "object");
map.set(function () {}, "function");
console.log(map.get(1)); // one
console.log(map.get({})); // undefined (같은 객체가 아님)
console.log(map.get(function () {})); // undefined (같은 함수가 아님)

위의 예제에서는 숫자, 객체, 함수를 키로 사용하는 예를 보여줍니다. 객체나 함수의 경우, 동일한 참조를 갖는 키를 사용할 때만 일치합니다.

순서 보장

Map은 삽입된 순서를 기억합니다. 즉, for...of 루프나 forEach 메서드를 사용하여 Map의 요소를 반복할 때, 삽입된 순서대로 요소를 가져옵니다.

javascript
const map = new Map();
map.set("a", 1);
map.set("b", 2);
map.set("c", 3);
for (let [key, value] of map) {
  console.log(key, value);
}
// a 1
// b 2
// c 3

반면, Object는 키의 순서를 보장하지 않습니다. ECMAScript 사양에 따르면, 대부분의 경우 객체 키는 삽입 순서대로 반복되지만, 명확하게 정의된 것은 아닙니다.

성능

Map은 많은 키-값 쌍을 자주 추가하거나 제거할 때 Object보다 더 나은 성능을 제공합니다. 특히, 대용량 데이터셋을 다룰 때 성능 차이가 두드러집니다.

3. Map의 메서드와 속성

Map은 다양한 유용한 메서드와 속성을 제공합니다.

주요 메서드

  • set(key, value): 키-값 쌍을 Map에 추가합니다.
  • get(key): 키에 해당하는 값을 반환합니다. 키가 존재하지 않으면 undefined를 반환합니다.
  • has(key): 키가 Map에 존재하는지 여부를 반환합니다.
  • delete(key): 키에 해당하는 값을 삭제합니다.
  • clear(): 모든 키-값 쌍을 삭제합니다.

주요 속성

  • size: Map 객체에 있는 키-값 쌍의 개수를 반환합니다.

4. Map의 실용적인 사용 예

데이터 구조 변환

다음 예제는 배열을 Map으로 변환하고, Map에서 다시 배열로 변환하는 방법을 보여줍니다.

javascript
const arr = [
  ["a", 1],
  ["b", 2],
  ["c", 3],
];
const map = new Map(arr);
console.log([...map]); // [['a', 1], ['b', 2], ['c', 3]]

캐싱

Map은 캐싱 메커니즘으로 유용합니다. 다음 예제는 간단한 캐시를 구현한 것입니다.

javascript
const cache = new Map();

function fetchData(key) {
  if (cache.has(key)) {
    return cache.get(key);
  } else {
    const data = /* 데이터를 가져오는 로직 */;
    cache.set(key, data);
    return data;
  }
}

5. Object와 Map의 적절한 사용 시점

Object를 사용해야 하는 경우

  • 간단한 키-값 저장소가 필요하고, 키가 문자열 또는 심볼일 때
  • 프로토타입 체인을 활용할 때
  • JSON과의 호환성이 중요할 때

Map을 사용해야 하는 경우

  • 다양한 유형의 키가 필요할 때
  • 데이터의 삽입 순서가 중요할 때
  • 많은 삽입과 삭제가 빈번히 일어날 때
  • 고성능 키-값 쌍 데이터 구조가 필요할 때

결론

Map은 ES6에서 도입된 이후로 많은 상황에서 Object보다 더 나은 선택이 될 수 있는 유용한 데이터 구조입니다. 다양한 키 타입 지원, 삽입 순서 보장, 뛰어난 성능 등 Map이 제공하는 이점은 복잡한 키-값 데이터 관리에 큰 도움이 됩니다. JavaScript 개발자는 MapObject의 특성을 잘 이해하고, 적절한 상황에서 올바른 도구를 선택하여 효율적이고 유지보수 가능한 코드를 작성할 수 있어야 합니다.