Map 객체는 키-값 쌍을 저장하는 집합이며 삽입 순서를 유지하는 JavaScript의 내장 객체다. 다음 예제는 Map 객체 price를 생성하고 과일과 가격에 관한 대응 데이터를 삽입한다.

const priceMap = new Map();
 
priceMap.set("apple", 1300);
priceMap.set("banana", 1100);
priceMap.set("kiwi", 1000);
 
console.log(priceMap.get("kiwi")); // 1000 출력
console.log(priceMap.size); // 3 출력

Object와 Map

역사적으로 JavaScript의 Object는 Map과 동일한 목적으로 사용되어왔다. 하지만 Map은 더 나은 보안적 기능과 키에 관한 추가적 기능을 포함한다.

  • 어떠한 키도 기본적으로 포함되지 않음: Object는 프로토타입의 키와 충돌할 가능성이 있다. Map은 기본적으로 키를 포함하지 않는다.
  • 키의 유형: Object는 String 또는 Symbol 타입의 키만 허용하는 반면, Map은 객체를 포함한 모든 값이 될 수 있다.
  • 항목의 순서: Object의 키는 항상 일관된 순서로 정렬되어 있음을 보장하지 않는다. Map은 삽입한 항목의 순서에 따라 키가 정렬된다.

더 자세한 차이점은 MDN의 Map 문서에서 찾아볼 수 있다.

WeakMap과 Map

WeakMap 객체는 메모리 누수를 방지하기 위해 고안된 키-값 쌍을 저장하는 집합이다. Map 객체 사용 목적은 유사하지만 키에 관한 처리와 일부 기능에 큰 차이가 있다.

  • 키 유형: WeakMap 객체의 키는 반드시 객체 또는 등록되지 않은 심볼이어야 한다.
  • 순회 불가: WeakMap은 GC에 의해 키로 지정된 객체가 수집될 수 있기 때문에 반복문(for ... of)를 사용할 수 없다.
  • 크기 추정 불가: 순회 불가한 이유와 마찬가지로 GC에 의해 키의 개수가 변동될 수 있기 때문에 크기를 알 수 없다.

다음 예제는 WeakMap 객체 인스턴스를 생성하고, appleObj 객체와 1800 숫자값을 대응시킨다. appleObj = null을 실행하면 { name: "apple" } 객체를 가리키는 변수가 존재하지 않게된다. WeakMap은 약한 참조를 가지기 때문에 해당 객체는 GC 대상이다. GC에 의해 키인 객체가 사라지면 그와 대응하고 있던 1800 숫자값과의 연결 쌍도 WeakMap에서 정리된다.

let appleObj = { name: "apple" };
 
const fruitMap = new WeakMap();
fruitMap.set(appleObj, 1800);
 
appleObj = null;  // GC에 의해 { name: "apple" } 객체와 1800 쌍을 메모리에서 정리
 
// fruitMap.get(appleObj)를 호출해도 appleObj가 null이라서 접근 불가

일반적인 키-값 저장 목적 외에 객체의 생명주기에 맞추어 자동으로 정리되어야 할 필요가 있다면 WeakMap을 사용하는 것이 권장된다.

참고 문헌