자바스크립트의 자료형 중 하나인 맵에 대해서 정리한다.
언뜻보면 객체와 유사해보이는 자료형으로,
키가 있는 데이터를 저장한다는 점에서 객체와 유사하지만 객체와 달리 키에 다양한 자료형을 허용한다.
Map | Object | |
---|---|---|
의도치 않은 key | 기본적으로 키를 포함하지 않으며, 명시적으로 입력된 내용만 포함한다. | prototype으로 인해 기본 키가 존재해, 주의하지 않으면 설정한 키과 충돌 할 수 있다. |
보안 | 사용자가 제공하는 키와 값에 대해서 안전하게 사용가능 | 사용자가 제공한 키-값 쌍을 공격자가 객체의 프로토타입을 재정의하여 객체 주입 공격을 발생시킬 수 있다. |
key 유형 | 모든 타입 가능 | string, symbol |
키 순서 | 삽입 순서대 | 일반적으로 정렬되어 있지만 항상 그런것은 아니다 결과적으로 속성 순서에 의존하지 않는 것이 가장 좋다. |
크기 측정 | iterable이므로 직접 반복 가능 | 수동으로 Object.keys()나 Object.entries()를 통해 반복 가능 항목을 얻을 수 있다. |
성능 | 키-값 쌍의 빈번한 추가 및 제거와 관련된 상황에서는 성능이 좀 더 좋다. | 키-값 쌍의 빈번한 추가 및 제거에 최적화되지 않아있다. |
직렬화 및 parsing | 기본 지원이 없다. | JSON.stringify()를 통한 JSON으로의 직렬화 지원 JSON.parse()를 통한 객체로의 구문분석 기본지원 |
new Map()
: 새로운 Map 객체를 생성map.set(key, value)
: key를 이용해 value를 저장, Map
객체를 반환map.get(key)
: key에 해당하는 값을 반환, 없다면 undefinedmap.has(key)
: key에 해당하는 값이 존재하는지 boolean 값으로 반환map.delete(key)
: key에 해당하는 값을 삭제, 성공 여부 boolean 값으로 반환map.clear()
: Map 객체의 모든 키-값 쌍을 제거map.size
: Map 객체의 키-값 쌍의 개수를 반환다음 메서드를 통해 각 요소를 반복해 사용할 수 있다.
map.keys()
: 각 요소의 키를 모은 iterable 객체를 반환map.values()
: 각 요소의 값을 모든 iterable 객체를 반환map.entries()
: 요소의 키-값 쌍을 모든 iterable 객체를 반환(for..of
반복문의 기초로 사용됨)let map = new Map([
['a', 100],
['b', 200],
['c', 50]
]);
// 키(vegetable)를 대상으로 순회.
for (let key of map.keys()) {
console.log(key); // cucumber, tomatoes, onion
}
// 값(amount)을 대상으로 순회
for (let value of map.values()) {
console.log(value); // 500, 350, 50
}
// 키-값 쌍을 대상으로 순회
for (let entry of map) { // map.entries()와 동일
console.log(entry); // cucumber,500 ...
}
다음 메서드들을 통해 Map을 객체로 또는 객체를 Map으로 변환 할 수 있다.
Object.entries : for..in
문과 같이 객체 자체와, 가까운 순서의 prototype의 모든 열거가능한 속성 키-값 쌍의 배열을 반환한다.
각 요소가 키-값 쌍인 배열이나 이터러블 객체를 초기화 용도로 Map에 전달해 새로운 Map을 만들 수 있다.
// 각 요소가 [키, 값] 쌍인 배열
let map = new Map([
['1', 'str'],
[1, 'num'],
[true, 'bool']
]);
console.log( map.get('1') ); // str
// 객체
let obj = {
name: "John",
age: 30
};
// 둘은 같은 형태를 가지고 있다.
Object.entries(obj) => [["name", "John"],["age", 30]]
let map = new Map(Object.entries(obj));
console.log( map.get('name') ); // John
Object.fromEntries : 키-값 쌍의 목록(iterable 객체)을 객체로 변환
키-값 쌍의 목록을 객체로 변환할 수 있다.
//각 요소가 [키, 값] 쌍인 배열
let prices = Object.fromEntries([
['banana', 1],
['orange', 2],
['meat', 4]
]);
//prices = { banana: 1, orange: 2, meat: 4 }
console.log(prices.orange); // 2
// Map
let map = new Map();
map.set('banana', 1);
map.set('orange', 2);
map.set('meat', 4);
let obj = Object.fromEntries(map.entries()); // === Object.fromEntries(map)
//{ banana: 1, orange: 2, meat: 4 }
console.log(obj.orange); // 2
자료형에 관계없이 유일한 값을 저장하는 값 컬렉션이다.
new Set(iterable)
: iterable 객체를 받으면(대부분 배열) 그 안의 값을 복사해 Set에 넣어준다set.add(value)
: 값을 추가, Set 객체를 반환set.delete(value)
: 값을 제거, 성공 여부를 boolean 값으로 반환set.has(value)
: 값이 존재 여부를 boolean 값으로 반환set.clear()
Set 객체의 모든 값을 삭제set.size
: Set 객체의 모든 값의 개수를 반환set.keys()
: Set 객체의 모든 값을 포함하는 iterable 객체를 반환set.values()
: Set.keys 와 동일 한 작업, Map과의 호환성을 위해 만들어졌다.set.entries()
: Set 객체의 가 값을 이용해 만든 [value, value]
배열을 포함하는 iterable 객체를 반환, Map과의 호환성을 위해 만들어졌다.for..of
나 forEach
를 사용해 반복할 수 있다.
let set = new Set(["oranges", "apples", "bananas"]);
for (let value of set) {
console.log(value);
}
// 둘다 동일하게 동작
set.forEach((value, valueAgain, set) => {
console.log(value);
});
forEach
가 다른 타입들이 사용할 때와 달리 두 번째 인자가 index가 아닌 첫 번째 인자와 같은 해당 값을 받는데, 이는 Map 과의 호환성을 위해서 이렇게 구현되었다.
Map
은 키-값 쌍으로 저장된 반복 가능 컬렉션이다.Set
은 중복 없는 유일한 값들이 저장된 반복 가능 컬렉션이다.Map과 Set이 반복작업을 할 땐, 해당 컬렉션에 요소나 값을 추가한 순서대로 진행된다.
그래서 이 두 객체는 정렬이 되어있지 않다고 할 수 없으나 컬렉션 내 요소나 값을 재 정렬하거나 (배열에서 인덱스를 이용해 요소를 가져오듯이) 숫자를 이용해 특정 요소나 값을 가지고 오는 것은 불가능 하다.
참고 사이트
Javascript.info-코어 자바스크립트-맵과 셋
MDN-Javascript 참고서-Map
MDN-Javascript 참고서-Set