이번 포스팅에서는 자바스크립트 배열 관련 함수 중 forEach, map, filter에 대해서 공부하고 이해한 내용을 정리하려고 한다.
세 가지 함수는 공통점이 있다.
1. 배열의 요소를 돌면서 매개변수로 받은 callback을 요소 각각에 실행시킨다.
2. 반복문을 멈출 수 있는 방법이 없다.
사실.. '안 되는 건 없다'는 마인드를 가진 사람으로서 지저분하게 하면 할 수는 있겠지만,, 다른 방법을 쓰겠다.
1번은 이해가 되는데, 2번이 이해가 되지 않는 사람이 있을 것이다.
많은 글에서 방법이 없다는 얘기는 하지만 왜 안 되는 건지에 대한 설명이 부족하다.
예를 들어 forEach 메서드가 동작하는 방식을 보면 왜 반복문을 멈출 수 없는지 알 수 있다.
const arr = [1, 2, 3, 4];
// forEach의 매개변수1
const callback = (item) => {
console.log(item);
if (item === 2) {
return; // 이렇게 사용해도 루프가 종료되지 않는다.
}
}
// Array.forEach
for (let i = 0; i < arr.length; i++) {
callback(arr[i]);
}
// 실행결과: 1 2 3 4
소스에서 보면 알 수 있듯이, forEach의 callback 안에서 return을 해봤자 실제 for문에는 영향이 없다는 걸 알 수 있다.
그럼 각 메서드들은 어떤 특징을 가지고 있는지, 무슨 차이가 있는지 한 번 알아보자.
1. forEach
forEach메서드는 주어진 함수를 배열 요소 각각에 대해 실행한다.
정말 단순하다. 이 메서드는 가독성을 빼면 시체라고 한다.(효율성은 for문이 더 좋기 때문에)
가독성이 정말 중요하다는 것은 알고 있지만, 상황에 따라서 효율성이 떨어질 수 있기 때문에 적절히 사용해야 할 것 같다.
반복문 실행 시 알아야 하는 부분은 '삭제했거나 초기화하지 않은 인덱스 속성에 대해서는 실행하지 않는다'는 점이다.
사용방법은 아래와 같다.
const arr = [1, 2, , 3, 4, 5];
arr.forEach((v, i, thisArr) => {
thisArr.splice(5,1);
console.log(v); // 1, 2, 3, 4
console.log(i); // 0, 1, 3, 4 => 2번째 인덱스가 null, 마지막 인덱스가 삭제되었으므로 방문하지않음.
});
2. map
map메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과(return 값)를 모아 새로운 배열을 반환한다.
원본 배열에 영향을 주지 않는다.
map메서드도 마찬가지로 '삭제했거나 초기화하지 않은 인덱스 속성에 대해서는 실행하지 않는다'는 특징이 있다.
하지만 새로운 배열을 확인해보면, 실행하지 않은 인덱스도 유지는 된다는 것을 알 수 있다.
사용방법은 아래와 같다.
const arr = [1, 2, , 3, 4, 5];
const newArr = arr.map((v, i, thisArr) => {
thisArr.splice(5,1);
console.log(v); // 1, 2, 3, 4
console.log(i); // 0, 1, 3, 4 => 2번째 인덱스가 null, 마지막 인덱스가 삭제되었으므로 방문하지않음.
return v*2;
});
// map 메서드 내 로직에 의해 arr이 변형되었다.
console.log(arr)
// 실행결과: [1, 2, undefined, 3, 4]
// map 호출시점 arr의 length가 유지된다.
console.log(newArr)
// 실행결과: [2, 4, undefined, 6, 8, undefined]
3. filter
filter메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.
원본 배열에 영향을 주지 않는다.
filter메서드도 마찬가지로 '삭제했거나 초기화하지 않은 인덱스 속성에 대해서는 실행하지 않는다'는 특징이 있다.
사용방법은 아래와 같다.
const arr = [1, 3, , 5, 6, 8];
const newArr = arr.filter((v, i, thisArr) => {
thisArr.splice(5,1);
console.log(v); // 1, 2, 3, 4
console.log(i); // 0, 1, 3, 4 => 2번째 인덱스가 null, 마지막 인덱스가 삭제되었으므로 방문하지않음.
return v%2 == 1;
});
// filter 메서드 내 로직에 의해 arr이 변형되었다.
console.log(arr)
// 실행결과: [1, 3, undefined, 5, 6]
// filter 조건에 통과하는 요소만 반환되었다.
console.log(newArr)
// 실행결과: [1, 3, 5]
'개발 > javascript' 카테고리의 다른 글
[javascript] 표준 내장 객체 Set, Map 정리 (1) | 2022.04.20 |
---|---|
[Javascript] 배열(Array)관련 함수(push, pop, shift, unshift, splice, slice) 정리 (0) | 2022.03.07 |
[JS] 자바스크립트 프로세스와 쓰레드 차이 (0) | 2022.03.03 |
[Javascript] 기본 개념과 동작 원리 이해의 중요성 (0) | 2022.02.25 |