37.2 Map
- Map 객체 : 키(key)와 값(value)의 쌍으로 이루어진 컬렉션
- 객체와 유사 but 차이가 있음
<객체 vs. Map 객체>
구분 | 객체 | Map 객체 |
---|
key로 사용할 수 있는 값 | 문자열 or 심벌 값 | 객체를 포함한 모든 값 |
이터러블 | X | O |
요소 개수 확인 | Object.keys(obj).length | map.size |
37.2.1 Map 객체의 생성
1) 인수를 전달 X : 빈 Map 객체가 생성됨
const map = new Map();
console.log(map);
2) 이터러블을 인수로 전달받아 Set 객체 생성
- 이때 이터러블은 key & value가 쌍으로 이루어진 요소로 구성돼야 함
const map1 = new Map([['key1', 'value1'], ['key2', 'value2']]);
console.log(map1);
const map2 = new Map([1, 2]);
- 중복된 key를 갖는 요소 존재 -> value가 덮어써짐
=> Map 객체엔 중복된 키를 갖는 요소 존재할 수 X
const map = new Map([['key1', 'value1'], ['key1', 'value2']]);
console.log(map);
37.2.2 요소 개수 확인
- Map.prototype.size 프로퍼티 사용
const { size } = new Map([['key1', 'value1'], ['key2', 'value2']]);
console.log(size);
- size 프로퍼티 - setter 함수 없이 getter 함수만 존재하는 접근자 프로퍼티임
=> size 프로퍼티에 숫자 할당해서 Set 객체의 요소 개수 변경 불가능
const map = new Map([['key1', 'value1'], ['key2', 'value2']]);
console.log(Object.getOwnPropertyDescriptor(Map.prototype, 'size'));
map.size = 10;
console.log(map.size);
37.2.3 요소 추가
- Map 객체에 요소 추가할 땐 Map.prototype.set 메서드 사용
const map = new Map();
console.log(map);
map.set('key1', 'value1');
console.log(map);
- set 메서드 : 새로운 요소가 추가된 Map 객체 반환함
-> set 메서드를 연속적으로 호출 가능
const map = new Map();
map
.set('key1', 'value1')
.set('key2', 'value2');
console.log(map);
- Map 객체에 중복된 key를 갖는 요소 존재할 수 X
-> 중복된 key를 갖는 요소 추가하면 에러 없이 value가 덮어써짐
const map = new Map();
map
.set('key1', 'value1')
.set('key1', 'value2');
console.log(map);
- Map 객체는 NaN과 NaN, +0과 -0은 같다고 평가 -> 중복 추가 허용 X
*) 일치 비교 연산자 (===)와의 차이 : (===)는 NaN과 NaN은 다름, +0과 -0은 같다고 평가
const map = new Map();
console.log(NaN === NaN);
console.log(0 === -0);
map.set(NaN, 'value1').set(NaN, 'value2');
console.log(map);
map.set(0, 'value1').set(-0, 'value2');
console.log(map);
- Map 객체는 key 타입에 제한 없음 -> 객체를 포함한 모든 값을 key로 사용 가능
(일반 객체와의 차이점임)
const map = new Map();
const lee = { name: 'Lee' };
const kim = { name: 'Kim' };
map
.set(lee, 'developer')
.set(kim, 'designer');
console.log(map);
37.2.4 요소 취득 - Set 객체와 다른 점!
- Map 객체에서 특정 요소 취득할 땐 Map.prototype.get 메서드 사용
const map = new Map();
const lee = { name: 'Lee' };
const kim = { name: 'Kim' };
map
.set(lee, 'developer')
.set(kim, 'designer');
console.log(map.get(lee));
console.log(map.get('key'));
37.2.5 요소 존재 여부 확인
- Map 객체에 특정 요소가 존재하는지 확인할 땐 Map.prototype.has 메서드 사용
- has 메서드 : 특정 요소의 존재 여부 나타내는 불리언 값 반환
const lee = { name: 'Lee' };
const kim = { name: 'Kim' };
const map = new Map([[lee, 'developer'], [kim, 'designer']]);
console.log(map.has(lee));
console.log(map.has('key'));
37.2.6 요소 삭제
- Map 객체에 특정 요소를 삭제할 땐 Map.prototype.delete 메서드 사용
- delete 메서드 : 삭제 성공 여부 나타내는 불리언 값 반환
const lee = { name: 'Lee' };
const kim = { name: 'Kim' };
const map = new Map([[lee, 'developer'], [kim, 'designer']]);
map.delete(kim);
console.log(map);
- 존재하지 않는 key로 Map 객체의 요소를 삭제하려 하면 에러 없이 무시됨
const map = new Map([['key1', 'value1']]);
map.delete('key2');
console.log(map);
- delete 메서드는 삭제 성공 여부 나타내는 불리언 값 반환하므로(set 메서드처럼 Map 객체를 반환하는게 아니라서) 연속적으로 호출 불가능
const lee = { name: 'Lee' };
const kim = { name: 'Kim' };
const map = new Map([[lee, 'developer'], [kim, 'designer']]);
map.delete(lee).delete(kim);
37.2.7 요소 일괄 삭제
- Map.prototype.clear 메서드 사용
- clear 메서드 : 항상
undefined
반환함
const lee = { name: 'Lee' };
const kim = { name: 'Kim' };
const map = new Map([[lee, 'developer'], [kim, 'designer']]);
map.clear();
console.log(map);
37.2.8 요소 순회
- Map.prototype.forEach 메서드 사용
: Array.prototype.forEach 메서드와 유사하게 콜백 함수 & forEach 메서드의 콜백 함수 내부에서 this로 사용될 객체(옵션)을 인수로 전달함
콜백 함수는 3개의 인수 전달받음
- 1번째 인수 : 현재 순회 중인 요소값(value)
- 2번째 인수 : 현재 순회 중인 요소키(key)
- 3번째 인수 : 현재 순회 중인 Map 객체 자체
const lee = { name: 'Lee' };
const kim = { name: 'Kim' };
const map = new Map([[lee, 'developer'], [kim, 'designer']]);
map.forEach((v, k, map) => console.log(v, k, map));
- Map 객체 - 이터러블임
-> for...of
문으로 순회 가능
-> 스프레드 문법 & 배열 디스트럭처링 할당의 대상이 될 수 있음
const lee = { name: 'Lee' };
const kim = { name: 'Kim' };
const map = new Map([[lee, 'developer'], [kim, 'designer']]);
console.log(Symbol.iterator in map);
for (const entry of map) {
console.log(entry);
}
console.log([...map]);
const [a, b] = map;
console.log(a, b);
- Map 객체 : 이터러블이면서 이터레이터인 객체를 반환하는 메서드를 제공
*) 34.6.3절 참고...
Map 메서드 | 설명 |
---|
Map.prototype.keys | Map 객체에서 요소키를 값으로 갖는 이터러블이면서 이터레이터인 객체를 반환 |
Map.prototype.values | Map 객체에서 요소값을 값으로 갖는 이터러블이면서 이터레이터인 객체를 반환 |
Map.prototype.entries | Map 객체에서 요소키와 요소값을 값으로 갖는 이터러블이면서 이터레이터인 객체를 반환 |
const lee = { name: 'Lee' };
const kim = { name: 'Kim' };
const map = new Map([[lee, 'developer'], [kim, 'designer']]);
for (const key of map.keys()) {
console.log(key);
}
for (const value of map.values()) {
console.log(value);
}
for (const entry of map.entries()) {
console.log(entry);
}
- Map 객체는 요소의 순서에 의미 X
- but, Map 객체를 순회하는 순서 = 요소가 추가된 순서