1. 키 타입이 왜 String이 되지?
- JS에서
Object.keys()
로 객체의 키값을 배열로 반환할 수 있다.
const object = {
a: '1',
b: 2,
c: 3,
};
console.log(Object.keys(object)); // ['a', 'b', 'c']
💡 그런데 만약 키 타입이 Number인 객체의 키값을
Object.keys()
로 추출하면 어떻게 될까?
Number 타입의 배열이 되나?
- 결과는 String 타입의 배열이 된다! 왜일까?
- 그 이유는
Object.keys()
가 String 타입의 배열을 리턴하는 함수이기 때문이다.(MDN 문서 참고)
const object = { 1: '일', 2: '이', 3: '삼', 4: '사' };
console.log(Object.keys(object)); // ["1", "2", "3", "4"]
만약, Number 타입의 객체 키값을 추출할 때 타입을 보장하고 싶다면?
- 데이터를
Map
으로 선언한 후,keys()
를 사용해 Number 타입의 키를 추출할 수 있다!
const map = new Map([[1, '일'], [2, '이'], [3, '삼'], [4, '사']]);
console.log(Array.from(map.keys())); // [1, 2, 3, 4]
- 그럼 이
Map
데이터는 어떤 특성을 가지고 있길래Object
와 달리 키 타입도 보장해주는 걸까? - 이번 시간에는
Map
에 대해 간단히 알아보고,Map
,Object
의 차이를 알아보았다!
2. Map 객체는 뭐죠?
1) Map 객체에 대해 알아보자
Map
객체는 키:값 쌍을 저장하는 데이터 형태이다.new Map()
을 사용해 선언할 수 있으며, 형태는Object
와 유사하다.
const map = new Map(); // Map {}
(1) 메서드 훑어보기
- 제공하는 메서드는 여러가지가 있는데, 코드로 예시를 살펴보았다.
메서드 | 설명 | |
---|---|---|
[1] | map.set(키, 값) |
- 키에 해당하는 값 추가 - 중복 키가 있을 때 값을 덮어씀 |
[2] | map.set(키, 값) |
- 키에 해당하는 값 제거 |
[3] | map.clear() |
- 모든 요소 제거 |
[4] | map.forEach(값, 키, map) |
- 데이터를 순회할 수 있음 |
const map = new Map([['key1', 'value1'], ['key2', 'value2']]);
// [1] 값 추가
map.set('key1', 'value111');
console.log(map); // Map(2) {key1: "value111", key3: "value3"}
// [2] 값 제거
map.delete('key1');
console.log(map); // Map(2) {key2: "value2", key3: "value3"}
// [3] 모든 값 제거
map.clear();
console.log(map); // Map {}
메서드 | 설명 | |
---|---|---|
[5] | map.keys() |
- 요소의 키를 반환 |
[6] | map.values() |
- 요소의 값을 반환 |
[7] | map.get(키) |
- key에 해당하는 값을 반환 |
[8] | map.has(키) |
- key가 존재하면 true - 존재하지 않으면 false를 반환 |
[9] | map.size |
- 요소의 개수를 반환 |
const map = new Map([['key1', 'value1'], ['key2', 'value2']]);
// [5] 요소의 키에 접근
console.log(Array.from(map.keys())) // ["key1", "key2"]
// [6] 요소의 값에 접근
console.log(Array.from(map.values())) // ["value1", "value2"]
// [7] 특정 값에 접근
console.log(map.get('key1')); // value1
// [8] 키가 있는지 확인
console.log(map.has('key2')); // true
// [9] 요소의 개수를 반환
console.log(map.size); // 2
📌
Map
의 메서드를 보니,Object
처럼 키 값 형태로 데이터가 선언되고
키로 데이터에 접근할 수 있는데Object
와 어떤 차이가 있는 걸까? 차이점에 대해 알아보자!
2) Map과 Object의 차이
(1) Map은 키 타입이 자유롭다
Map
은 키에 모든 데이터 타입이 가능하다!- 그래서 키 타입이 Number도 가능하다.
const map = new Map();
map.set(11, '숫자 11');
map.set(22, '숫자 22');
console.log(map); // Map {11: "숫자 11", 22: "숫자 22"}
console.log(map.get(11)); // 숫자 11
console.log(map.get("11")); // undefined
- 그에 반해
Object
는 키 타입이 문자열이나Symbol
만 가능하다. - 만약 데이터의 키 타입을 Number로 지정해도 문자열로 형변환된다.
const object = {11: '숫자 11', 22: '숫자 22'};
console.log(object); // {"11": "숫자 11", "22": "숫자 22"}
- 다행히도
Object
는 Number 타입의 키를 넘기나 String 타입의 키를 넘기나 값에 접근할 수 있다.
console.log(object[11]); // 숫자 11
console.log(object["11"]); // 숫자 11
(2) Map은 추가한 순서로 데이터가 구성된다
Map
은 데이터를 추가한 순서대로 데이터가 정렬된다.- 그래서 순서가 보장되어야 하는 경우에 유용하다.
const map = new Map();
map.set(11, '숫자 11');
map.set(22, '숫자 22');
map.set(0, '숫자 0');
map.set(999, '숫자 999');;
console.log(map);
// Map {11: "숫자 11", 22: "숫자 22", 0: "숫자 0", 999: "숫자 999"}
- 그러나
Object
는 데이터를 추가한 순서대로 정렬되지 않는다.
const object = {11: '숫자 11', 22: '숫자 22'};
object[0] = '숫자 0';
object[999] = '숫자 999';
console.log(object);
// {0: "숫자 0", 11: "숫자 11", 22: "숫자 22", 999: "숫자 999"}
(3) Map은 그 자체로 iterable 하다
Map
은 그 자체로 순회가능(iterable)한 데이터이므로,for ~ of
,forEach
로 순회할 수 있다.
const map = new Map();
map.set(11, '숫자 11');
map.set(22, '숫자 22');
for (const value of map) {
console.log(value);
}
// [11, "숫자 11"]
// [22, "숫자 22"]
map.forEach((value) => {
console.log(value);
})
// 숫자 11
// 숫자 22
Object
는 그 자체로 순회가능한 데이터가 아니므로 반복문 사용시 not iterable 에러가 발생한다.
const object = {11: '숫자 11', 22: '숫자 22'};
// TypeError: object is not iterable
for (const value of object) {
console.log(value);
}
- 그래서
Object
는 별도의 가공(ex.Object.keys
)를 거쳐야 반복문을 사용할 수 있다.
const object = {11: '숫자 11', 22: '숫자 22'};
for (const key of Object.keys(object)) {
console.log(object[key]);
}
// 숫자 11
// 숫자 22
(4) Map은 값 제거, 추가에 대한 성능이 ‘조금 더’ 좋다
- MDN 공식문서에 따르면, 키 값 쌍의 빈번한 추가를 하거나 제거를 할 때
Map
이Object
보다 성능이 좀 더 좋다고 한다. - 만약 값의 추가, 제거가 빈번하다면
Map
을 한 번 고려해봐도 좋을 듯 하다.
3. 마치며
- 이번 시간에는 객체의 키 타입을 보장해주는
Map
객체에 대해 보았다. Map
은Object
와 달리, 키를 어떤 타입으로도 선언할 수 있으며, 추가한 순서로 데이터가 구성되고, 값의 추가와 제거에 대한 성능이 좋다는 특징이 있었다.- 또한
Map
은 그 자체로 iterable하므로 반복문을 사용하여 데이터를 순회할 수 있다. - 암묵적으로
Object
로 데이터를 구성하기 보다는, 상황에 따라Map
을 한 번 사용해보면 어떨까?
+) 참고자료
반응형
'개발 기술 > 사소하지만 놓치기 쉬운 개발 지식' 카테고리의 다른 글
input 유효성에 따라 스타일링하는 3가지 방법 (invalid, user-invalid, out-of-range) (0) | 2024.01.06 |
---|---|
[CSS] 왜 transform 애니메이션 성능이 좋을까? (with. GPU, Reflow) (0) | 2023.11.28 |
[html] 더 나은 사용자 입력을 위한 inputmode 속성 (0) | 2023.08.20 |
[모노레포] 특정 폴더를 패키지화하는 방법 (0) | 2023.05.15 |
[CSS] 렌더링 퍼포먼스를 높여주는 content-visibility (0) | 2023.05.07 |
댓글