map vs forEach

자바스크립트로 개발시 배열을 반복하는 방법으로 많이 사용되는 메서드이다. 이 둘을 처음 접하면 언제 어떤 것을 쓰는게 좋은지 헷갈릴때가 많다. 간단한 개념이지만 짚고 넘어가자.

간단한 정의

Array.prototype.map()

map 메서드는 매개 변수로 함수를 받는다. 그런 다음 각 요소에 매개 변수로 받은 함수를 적용하고 완전히 새로운 배열로 반환하게 된다.

const arr = [1,2,3];
const arr2 = arr.map(x => x*2);

console.log(arr); // [1,2,3]
console.log(arr2); // [2,4,6]

Array.prototype.forEach()

forEach 메서드는 매개 변수로 함수를 받는다. 그런 다음 각 요소에 매개 변수로 받은 함수를 적용하고 undefined를 반환한다.

const arr = [1,2,3];
const arr2 = arr.forEach(x => x*2);

console.log(arr); // [1,2,3]
console.log(arr2); // undefined

차이점

성능의 차이는 솔직히 잘 모르겠다. jsbench로 두가지 케이스를 하드하게 돌렸을때 결과가 엎치락 뒤치락 했기 때문이다. 성능의 차이로 이 두 메서드중 어떤 것을 쓸지 말지 결정하기보단 적절한 케이스에 맞게 쓸 수 있도록 하자.

반환값

map은 매개변수로 받은 함수를 적용된 새배열을 반환하지만, forEachundefined를 반환한다.

체이닝

map 메서드의 경우 새배열이 반환되기 때문에 다른 배열관련 메서드로 체이닝이 가능하다.

const arr = [1,2,3];
const arr2 = arr.map(x => x*2).filter(x => x / 2 === 2);
console.log(arr2); // [4]

arr.forEach(x => x*2).filter(x => x / 2 === 2);
// Uncaught TypeError: Cannot read property 'filter' of undefined

원본 배열을 수정하는가?

두 메서드 모두 원본 배열을 수정하지는 않는다. 하지만 매개 변수로 넣어준 콜백함수에서 직접 원본 배열을 수정한다면 두 메서드 모두 원본 배열이 수정된다.

arr.forEach(x => x*2); // arr => [1,2,3]
arr.map(x => x*2); // arr => [1,2,3]
 
 // ---------------------
 
arr.map((x,i) => arr[i] = x*2); // arr => [2,4,6];
// or
arr.forEach((x,i) => arr[i] = x*2); // arr => [2,4,6];

언제 어떤 메서드를 사용하는 것이 좋을까?

매개변수가 적용된 새배열이 필요하다면 map 메서드를 사용하고, 만약 반환된 배열이 필요가 없다면 forEach를 사용하자.

Last updated