JS 배열 메서드『map() │ forEach()』
for, if구문이 꼬리에 꼬리를 물고 있는 코드는 작업시간을 잡아먹는 괴물이다.
for 혹은 if구문이 난잡하게 널려있는 코드를 보면 정신이 혼란하다.
결론적으로 for구문을 될 수 있는 한 사용하지 않고,
배열메서드를 사용하는 편이 클린코드에 가깝다.
(자료구조에 따라 for..of, for...in문이 효율적일 수 있음)
* fruits배열에서 '폰' 데이터는 몇개인가?
let fruits = ['사과', '오렌지', '사과폰', '바나나', '딸기', '바나나폰', '파인애플', '수박', '오렌지폰']
위와같은 문제를 풀기위해 for구문을 사용한다면
아래와 같이 for문 내에서 if조건문을 사용하는 방법을 생각할 수 있다.
for(let i=0; i<fruits.length; i++){
if(fruits[i].match(/폰/)){
console.log('폰:'+fruits[i]);
}
}
그런데
만일 fruits데이터의 내부값이 객체라면 어떨까?
let fruits = [
{
name:'사과',
state:'특상',
price:'2,000원'
},
{
name:'오렌지'
state:'중하',
price:'1,500원'
},
{
name:'사과폰pro10'
state:'중고',
price:'1100000원'
},
{
name:'바나나'
state:'상급',
price:'800원'
},
{
name:'딸기'
state:'중급',
price:'400원'
},
{
name:'바나나폰'
state:'신동품',
price:'50000원'
},
{
name:'파인애플'
state:'하급',
price:'2000원'
},
{
name:'수박'
state:'중상급',
price:'6000원'
},
{
name:'오렌지폰'
state:'중급',
price:'10000원'
}
];
for구문이 3개 이상 중첩되기 시작하고, 그 사이에 조건문까지 개입되면
아래와 같이 점차 알아보기 힘든 코드가 된다.
for(let i=0; i<fruits.length; i++){
for(let item in fruits[i]){
for(let j=0; j<item.length; j++){
if(item[j].value.match(/폰/){
console.log('폰입니다');
}else{
return item[j].value;
}
}
}
}
위와같은 상황에서 필요한 도구가 '배열메서드'이다.
배열 메서드는 스파게티 코드가 되어가는 상황을 풀어줄 수 있는 훌륭한 도구다.
│Map( )
map(), forEach()메서드의 가장 큰 차이점은 '반환값' 유무이다.
map()의 경우, 데이터에서 필요한 값을 새로운 배열 형태로 반환할 수 있다.
map()을 사용하기 좋은 케이스는
기존의 속성을 뽑아내어 새로운 유형(전기차=새로운 배열)을 생성하는 것과 비슷하다.
│forEach( )
forEach()메서드는 반환값이 없다.
원본 배열의 개별값을 하나씩 수정하는 방식이며,
기존의 데이터를 통해 뭔가 새로운 형태를 만들어내기보다
기존의 것을 튜닝하는 상황에 적합하다.
│결과
위의 fruits데이터를 map(), forEach()구문으로 정리하면 아래와 같다.
//fruits1, fruits2는 fruits 데이터와 같음
console.log('================map=================')
let res1 = fruits1.map((fruit1)=>{ return fruit1.name='참외'; });
res1.push({name:'감',state:'중급',price:'4000원'});
console.log(fruits1);
console.log(res1);
console.log('================forEach=================')
let res2 = fruits2.forEach((fruit2)=>{ fruit2.name ='참외' });
//forEach()구문은 추가 불가 **// res2.push({name='감',state:'중급',price:'4000원'});
console.log(fruits2);
console.log(res2);
map()메서드의 경우, 새로운 배열이 생성되면서 '감'객체가 추가되었고,
forEach()의 경우, 새로운 배열이 없으므로 'undefined'가 출력된다.
새 배열의 생성유무는 상당히 중요한데,
다음과 같이 코드의 직관성(체이닝)이 달라지기 때문이다.
let res1 = fruits1.map(fruit=>fruit)
.filter(item=>(item.name ==='오렌지폰') ? item : false)
console.log(res1);
결론적으로,
for구문을 사용할 수밖에 없는 상황이 아닌 이상,
코드를 읽는 팀원들을 배려한다는 기준에서
배열 메서드를 사용하는 편이 좋다.