map() 메서드 / forEach() 메서드

18840 단어 jsjs

이해안가는 점 정리해보기
참고 : BigTop_Log

map()

map 메서드란? 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환하는 메서드이다. for of 문이나 forEach처럼 배열 내 요소들을 반복하는 반복문의 한 종류인데, 조금 독특한 부분은 매 반복마다 return되는 결과에 따라 새로운 배열을 만들어낸다는 것이다.

const myArr = [1, 2, 3, 4, 5];

const newMyArr = myArr.map((currentElement, index, array) => {
    return currentElement * 2
});

console.log(newMyArr); // [2, 4, 6, 8, 10]

map메서드는 파라미터로 콜백함수를 받는데, 그 콜백 함수의 파라미터는 요소, index 그리고 현재 map메서드를 호출한 배열이다.

세번째 배열은 잘 사용되지 않고 일반적으로 첫 번째 요소와, 두 번째 index가 많이 사용된다.

말 그대로 요소는, 반복이 일어날 때마다 0번 index부터 해당하는 각 요소가 할당되고, index 또한 해당 index인 것이다.

const myArr = [1, 2, 3, 4, 5];

const newMyArr = myArr.map((currentElement, index, array) => {
    console.log(`요소: ${currentElement}`);
    console.log(`index: ${index}`);
    
    return currentElement * 2
});

console.log(newMyArr); // [2, 4, 6, 8, 10]

이러면 다음과 같은 결과가 출력됩니다.

여기까지만 보면 forEach와 다를 것이 없지만, 차이점은 마지막 10번 줄에서 확인한 것처럼 이 메서드가 실행된 자리에 리턴되는 배열이 있느냐이다.

결과적으로 map은 메서드를 호출한 배열의 길이 만큼의 새로운 배열을 만들어내는 게 핵심인데, 콜백 함수의 return 값을 통해 새로운 배열들의 각 요소를 변형할 수 있다는 특징이 있는 것이다.

간혹 forEach의 기능을 포괄한다고 생각해서, 이런 류의 작업을 모두 map으로만 사용하는 경우도 있는데, 개인적으로는 가급적 목적에 맞는 최적화된 문법을 사용하는 것이 좋다고 생각한다.

아래 코드를 좀 더 살펴보면

const myArr = [1, 2, 3, 4, 5];
const assignMyArr = myArr;
const mapMyArr = myArr.map((el) => {    
    return el
});

console.log(myArr); // [1, 2, 3, 4, 5]
console.log(assignMyArr); // [1, 2, 3, 4, 5]
console.log(mapMyArr); // [1, 2, 3, 4, 5]

3번째 줄에서 map메서드의 콜백 함수를 실행할 때, 사용하지 않는 파라미터는 생략할 수 있다.
그리고 그냥 요소값을 return 하게 되면 똑같은 배열이 만들어지는데,
그렇다 하더라도 map메서드를 통해 생성된 배열은 말 그대로 새로운 배열이기 때문에,
배열의 요소들이 서로 같더라도 아래와 같이 각 배열들을 일치 비교할 경우 결괏값이 서로 차이가 난다.

console.log(myArr === assignMyArr); // true
console.log(myArr === mapMyArr); // false

끝으로 만약 map메서드의 콜백 함수가 아무것도 리턴하지 않을 경우에는,
호출한 배열의 길이만큼의 undefined가 채워진 배열이 리턴된다.

const myArr = [1, 2, 3, 4, 5];
const mapMyArr = myArr.map(() => {});

console.log(mapMyArr); // [undefined, undefined, undefined, undefined, undefined]

forEach()

forEach() 메서드는 배열에 활용이 가능한 메서드로, 파라미터(매개변수)로 주어진 함수를 배열 요소 각각에 대해 실행하는 메서드이다. map() 메서드와 거의 비슷하지만 차이점은 따로 return하는 값이 없다는 점이다.

const myArr = [1, 2, 3, 4, 5];

const newMyArr = myArr.forEach((currentElement, index, array) => {
    console.log(`요소: ${currentElement}`);
    console.log(`index: ${index}`);
    console.log(array);
});

console.log(newMyArr); // undefined

forEach 메서드도 map 메서드와 동일하게 파라미터로 콜백 함수를 받는데, 그 콜백 함수의 파라미터는 요소, index 그리고 현재 map 메서드를 호출한 배열이다.
forEach 메서드도 세번째 배열은 잘 사용되지 않고 일반적으로 첫 번째 요소와, 두 번째 index가 많이 사용된다.

앞에서도 언급했지만, map 메서드와 차이점은 따로 콜백 함수가 return 하는 값을 따로 모아서 어떤 처리를 하는 과정이 없기 때문에, 메서드를 호출한 코드를 함수에 할당하면 undefined가 할당된다.

그래서 forEach 메서드는 변수에 할당하기 보다는 반복문이나 조건문과 같이 그냥 바로 호출되는 것이 일반적이다.

const myArr = [1, 2, 3, 4, 5];

myArr.forEach((currentElement, index, array) => {
    console.log(`요소: ${currentElement}`);
    console.log(`index: ${index}`);
    console.log(array);
});

위 코드를 실행한 결과는 다음과 같다.

map메서드에서도 살펴본 것과 같이 사용하지 않는 콜백함수의 파라미터는 (뒤에서부터 순서대로), 생략해도 된다.

const myArr = ['강아지', '고양이', '햄스터', '거북이', '이구아나'];

myArr.forEach((el, i) => {
    console.log(i);
    console.log(el);
    if(el === '고양이') {
    	myArr.shift();
    }
})

console.log(myArr); // ["고양이", "햄스터", "거북이", "이구아나"]

그리고 forEach 메서드의 콜백함수 내에서 메서드를 호출한 배열을 변경하는 것이 가능한데,
위 코드처럼 특정상황에서 요소 하나를 삭제해버리게 되면 그 다음 요소를 찾을 때, 변경된 배열에서 해당하는 index를 찾기 때문에 이 코드의 실행결과를 보면 고양이 다음에 거북이가 출력되는데,
메서드가 실행된 이후에 myArr를 살펴보면, 강아지가 배열에서 삭제된 걸 확인할 수 있다.

참고

shift() 메서드는 배열에서 첫 번째 요소를 제거하고, 제거된 요소를 반환합니다. 이 메서드는 배열의 길이를 변하게 합니다.

좋은 웹페이지 즐겨찾기