
map() 메서드는 자바스크립트 배열 메서드 중 하나로, 배열의 각 요소에 대해 제공된 함수를 호출한 결과를 새로운 배열로 반환한다.
따라서 원본 배열을 변경하지 않으며, 반환값이 필요한 작업에 주로 사용된다.
map() 메서드는 새로운 배열을 반환하기 때문에 forEach()와 달리 체이닝이 가능하며, 배열의 각 요소를 조작하거나 변환하여 반환값을 따로 저장하고 싶을 때 적합하다.
이 메서드는 원본 배열을 안전하게 유지하면서 새로운 데이터를 생성할 때 사용하면 효율적이며, 다른 배열 메서드와 함께 체이닝하여 쉽게 작성할 수 있다. (우테코 프리코스 피드백에선 가독성 및 유지보수 측면 때문에 체이닝 사용을 지양하라고 했지만 말이다...)
그러나 map() 메서드가 원본 배열을 변경하진 않지만 여전히 callback 함수에 의해서 원본 배열이 변형될 수는 있으므로 콜백 함수 내부 로직 작성 시 주의하는 게 좋다.
map() 메서드의 기본 문법은 다음과 같다:
array.map(callback(element, index, array), thisArg);
이렇듯 이 메서드는 순서대로 콜백 함수(필수 인자)와 콜백 함수에 쓰일 this 값(선택 사항 인자)를 받는다.
물론 두 번째 인자인 this 값을 정의하는 thisArg는 콜백 함수가 화살표 함수가 아닌 function 키워드로 정의되었을 때에만 유효하다.
왜냐하면 화살표 함수는 자신만의 this를 가지지 않으며, 바깥 스코프의 this를 상속받기 때문이다. 따라서 화살표 함수로 작성하고 thisArg를 전달하면 이 값은 무시된다.
콜백 함수는 (현재 요소, 현재 요소의 인덱스, 참조 중인 원본 배열) 이렇게 세 가지의 인자를 가질 수 있다.
callback: 배열의 각 요소를 처리할 함수 (필수)
element: 처리 중인 현재 요소.index: 처리 중인 현재 요소의 인덱스.array:map()메서드를 호출한 원본 배열.
thisArg: 콜백 함수 내부에서 사용될 this 값을 설정 (선택 사항)
for문으로 작성한 배열 요소를 대문자로 바꾸는 로직을 map() 메서드를 사용해 리팩토링한 예시이다.
const items = ["item1", "item2", "item3"];
// 리팩토링 전 for문 사용
// 빈배열 초기값을 만들고 items 요소를 순회하며 push
const uppercasedItems = [];
for (let i = 0; i < items.length; i++) {
uppercasedItems.push(items[i].toUpperCase());
}
console.log(uppercasedItems);
// 출력: ["ITEM1", "ITEM2", "ITEM3"]
// 리팩토링 후 map() 사용
// map()이 새로운 배열을 반환하므로 바로 할당
const uppercasedItemsWithMap = items.map((item) => item.toUpperCase());
console.log(uppercasedItemsWithMap);
// 출력: ["ITEM1", "ITEM2", "ITEM3"]
map()은 배열의 각 요소를 변경하거나 새 배열로 변환해야 할 때 유용하다. 이 메서드는 항상 새 배열을 반환하므로 체이닝(chaining) 작업에도 적합하다.
const numbers = [1, 2, 3];
const doubledNumbers = numbers
.map((num) => num * 2) // 각 요소를 두 배로
.map((num) => num + 1); // 결과에 1을 더함
console.log(doubledNumbers);
// 출력: [3, 5, 7]
map() 메서드는 원본 배열을 변경하지 않고 대신 각 요소를 처리한 결과로 새로운 배열을 반환한다.
const arr = [1, 2, 3, 4];
const updatedArr = arr.map((value) => value * 2);
console.log(arr); // 원본 배열: [1, 2, 3, 4]
console.log(updatedArr); // 새로운 배열: [2, 4, 6, 8]
map() 메서드는 forEach()처럼 배열의 모든 요소를 반드시 순회하며, 중간에 반복을 멈출 수 없다. break 문이 필요한 경우 for문이나 for...of를 사용해야 한다.
콜백 함수 내부 로직에서 특정 조건에 따라 해당 호출을 조기에 종료하고 값을 반환하는 것은 아래와 같이 if문에 return 을 작성하는 등으로 가능하다.
const arr = [1, 2, 3, 4, 5];
const processedArr = arr.map((value) => {
if (value === 3) {
return "중단";
}
return value;
});
console.log(processedArr);
// 출력: [1, 2, "중단", 4, 5]
map()은 비동기 작업을 지원하지 않으므로, 콜백 함수에서 async를 사용하는 경우 비동기 작업이 완료되기 전에 결과를 반환한다. 따라서 비동기 작업을 처리하려면 Promise.all() 을 함께 사용해 병렬 처리하거나 비동기 작업을 지원하는 for...of 혹은 reduce()를 대신 사용해야한다.
const asyncTask = async (value) => value * 2;
const arr = [1, 2, 3];
// 비동기 작업 병렬 처리 예시
const asyncResults = Promise.all(arr.map(asyncTask));
asyncResults.then((results) => console.log(results));
// 출력: [2, 4, 6]
| 구분 | map() | forEach() |
|---|---|---|
| 반환값 | 새로운 배열을 반환 | 반환값이 없으며 항상 undefined |
| 용도 | 배열 요소를 변환하여 새로운 배열 생성 | 부수 효과를 발생시키는 작업에 적합 |
| 체이닝 | 가능 | 불가능 |
글 작성 참고 사이트: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map
참고 서적: 자바스크립트 완벽 가이드