자바스크립트에서 map은 두 가지이다
1. Array.prototype.map() : 특정 배열 내 모든 요소에 대해 각각 함수를 적용하고, 새로운 배열로 만들어서 반환한다. 이때 원본 배열에는 영향을 주지 않는다
2. Map : Java의 HashMap와 같은 key:value로 이루어진 자료구조
자바스크립트를 공부하다가 Map이 Java와는 다른 걸 느꼈다. Java에서 Map 객체는 키-값을 쌍으로 저장하며 각 쌍의 삽입 순서도 기억하는 콜렉션이다. 아무 값이라도 키와 값으로 사용할 수 있다. 즉, key:value 형식으로 저장되며, key 값을 사용하여 해당 key에 맞는 value값을 가져올 수 있다
let max = new Map();
// set으로 맵 객체에 삽입
max.set("id", 0);
max.set("이름", "마이클");
max.set("전공", "영문학");
max.set("나이", 25);
// 이차원 배열로 넘겨주는 것도 가능합니다
let michael = new Map([
["id", 0],
["이름", "마이클"],
["전공", "영문학"],
["나이", 29]
])
// get으로 맵 객체 조회
max.get("이름"); // "마이클"
// delete로 삭제
max.delete("나이"); // 삭제가 성공하면 true를 반환
// clear로 맵 안의 프로퍼티 전부삭제
max.clear();
- 맴 객체는 기존 객체와는 다르게 메소드만을 이용해 값을 넣고 뺀다
- 기본적으로 삽입, 조회, 삭제를 할 수 있다
Array.map()
이러한 map 메서드는 배열을 반복해주는데, callback 함수에서 reutnr한 값으로 (each) 요소를 수정해 준다. map 메서드의 리턴값은 수정된 값으로 생성된 배열이다
const numbers = [1, 2, 3, 4, 5];
const result = numbers.map(number => number * number);
console.log(numbers); // [1, 2, 3, 4, 5];
console.log(result); // [1, 4, 9, 16, 25]
- 주어진 array의 값들을 map으로 제곱을 해서 다시 result안에 배열을 만들어준다
- 여기서 numbers라는 배열에는 아무런 영향이 없는 걸 볼 수 있다
위에 예시를 for문으로 돌린다면
const numbers = [1, 2, 3, 4, 5];
const result = []; for (i = 0; i < numbers.length; i++) {
result.push(numbers[i] * numbers[i]);
}
console.log(result); // [1, 4, 9, 16, 25]
- 보이다시피 map메서드는 간결하지만 for문을 사용하면 순환이라는 부분까지 직접 처리해야 하기 때문에 좀 더 길고 간결하지가 않다
장점
문자열 아닌 값도 키로 사용 가능하다
객체에서는 문자열 (string) 혹은 심볼 (symbol)만 프로퍼티의 키로 사용할 수 있었지만 맵 객체에서는 함수나 객체를 포함해서 모든 자료형이 키로 쓰일 수 있다
- 문자열이 아닌 숫자일 때 보기 더 편한 경우도 있다
메서드 사용의 명확성
객체처럼 . 이나 []로 접근하지 않고 메소드만으로 객체의 프로퍼티들을 수정하거나 조회할 수 있으므로 객체보다 동작과 의도를 더 정확하게 보여준다
let maxInfoObj = {
name:"voyage",
age:29,
major:"경영정보",
}
const maxInfoMap = new Map([
["name", "voyage"],
["age", 29],
["major", "경영정보"],
])
// 객체 : let으로 선언해 빈 객체 할당해서 빈 객체로 초기화
maxInfoObj = {}
// 맵 객체 : clear 메소드 사용해 빈 맵 객체로 초기화
maxInfoMap.clear()
깔끔한 순회
맴 객체의 가장 장점이라고 생각되는 부분이다. 맴 객체는 그 자체로 for..of문을 통해 순회가 가능하다. 맵 이터레이터의 형태로 이루어지는데 키-값을 쌍으로 묶은 배열이다. entries 메소드로 확인할 수 있다
const maxInfoMap = new Map([
["name", "voyage"],
["age", 29],
["major", "경영정보"],
])
maxInfoMap.entries();
// MapIterator { ["name", "voyage"],["age", 29],["major", "경영정보"]}
for (const [key, value] of maxInfoMap) {
console.log(key, value);
}
// 결과
// "name" "voyage"
// "age" 29
// "major" "경영정보"
주의사항
- map 함수는 객체를 직접 사용하거나 변경시키지는 않지만 callback 함수를 통해 수정할 수 있으며 이는 문제를 발생시키는 원인이 된다
- callback 함수가 호출되는 범위는 콜백함수가 처음 호출되기 이전이며, map이 순회하는 도중에 추가된 요소는 접근하지 않는다. 반대로 순회하는 도중 수정이 일어나면 변경된 값이 콜백함수에 전달되고 삭제된 요소는 접근하지 않는다
// array 요소가 추가되는 경우
const numbers = [1, 2, 3, 4, 5];
const result = numbers.map(number => {
numbers.push(number);
return number * number;
});
console.log(result); // [1, 4, 9, 16, 25];
// array 요소가 수정되는 경우
const numbers = [1, 2, 3, 4, 5];
const result = numbers.map(number => {
numbers.pop(); return number * number;
});
console.log(result); // [1, 4, 9, empty × 2];
결론
맵 객체는 객체의 프로퍼티를 자주 변경해야할 때 빛을 발한다. 메서드 이름들이 예측 가능하여 동작이 명확하고, 기존 객체와 달리 순회도 쉽게 이러우져 데이터를 조작하기 적합하다
출처 : 아래의 사이트들을 보면서 큰 공부 하였습니다
https://maxkim-j.github.io/posts/js-map
https://erim1005.tistory.com/entry/Javascript-에서-Object를-해시맵처럼-사용하지-마세요
https://dev-note-97.tistory.com/276
'Front-End > JavaScript' 카테고리의 다른 글
Vanilla JavaScript로 React Hooks 구현하기 (0) | 2024.03.25 |
---|---|
프로토타입 (Prototype)과 객체지향 프로그래밍 (0) | 2024.03.25 |
[JavaScript] this란? (0) | 2022.03.13 |
[JavaScript] Closure (클로저) (0) | 2022.03.09 |
[JavaScript] var / let / const 변수 (0) | 2022.03.09 |