TIL. [javascript] Array method (map, for each)

문병곤·2020년 11월 22일
0
post-custom-banner

mapfor each는 ES5에서 지원하는 Array method다. Arrow function과 관련된 내용을 공부하던 중 mapfor each를 사용해서 배열의 반복문을 만드는 것을 보고 이해가 잘 되지 않았기에 좀 더 공부를 해봤다.

두 메서드는 특히 callback 함수로 많이 사용된다. Callback 함수란 다른 함수의 매개변수로서 함수를 전달하고 특정 이벤트 발생 뒤 매개변수로 전달된 함수가 다시 호출되는 것을 의미한다. 간단히 말하면, 특정한 다른 함수가 실행을 끝낸 뒤에야 실행(callback)되는 함수를 말한다. 때문에 block형 함수가 아니며 비동기 방식이다.

이러한 작동 방식이 특별한 이유는 자바스크립트가 이벤트 기반의 언어기 때문이다. 자바스크립트는 다음 명령어를 실행하기 위해 앞선 명령어의 응답이 필요없다. 즉 자바스크립트에서 어떠한 앞선 명령어의 결과 가 도출되지 않았더라도 다음 명령어가 실행된다는 의미다. 더 쉽게 말하자면 앞 명령과 뒷 명령은 바톤터치를 하지 않는다. 그런데 만약 특정 함수가 반드시 앞선 이벤트로 인해 발생한 결과 값이 필요하다면? 그때 사용되는 것이 callback함수다.

다시 앞으로 돌아가 mapfor each에 대해 알아보자.

Array.map()

map 메서드는 배열.map((요소, 인덱스, 배열) => { return 요소}); 이런 모양을 가지고 있다. 작동 원리는 반복문을 돌며 배열 안의 요소들을 1:1로 짝 짓는 방식이다. 어떻게 짝 지을지 정의된 함수가 메서드의 인자로 들어간다. Map 메서드의 return값은 수정된 값으로 다시 생성된 배열이다. Return이 내장된 메서드이기에 요소들이 자동으로 Callback된다.

const arr = [1, 2, 3]; 
const squares = arr.map(x => x * x); // const arr = [1, 2, 3]; const squares = arr.map(x => x * x);과 동일

위의 함수를 예로 들면, square함수는 array 타입인 arr = [1,2,3]의 요소 갯수(3)만큼 반복된다. 반복될 때마다 실행된 함수는 인자로 전달되고 이 callback 함수는 arr의 요소를 인자(x)로 받는다. 기존 객체를 수정하지 않아도 되며, 함수 안에 적은 대로 반환할 수 있기 때문에 자유도가 높은 장점이 있다.


Array.forEach()

forEach는 array.forEach(callback(currentvalue[, index[, array]])[, thisArg]) 이러한 구조를 가졌다. array를 다룰 때 for 대신 사용한다. 끝을 지정해주는 다른 반복문과 달리, 인자로 들어온 배의 내부 인덱스 끝까지 알아서 순환을 해준다. foreach구문의 인자로 callback함수를 등록할수 있고, 배열의 각 요소들이 반복될 때 callback 함수가 호출된다.

const animals = ["lion", "tiger"]; 
animals.forEach(animal => { 
	console.log(animal); 
});

위의 예시의 결과는 lion tiger이다. map을 사용해도 결과는 같겠지만 forEach에는 return하는 것이 없다는 차이가 있다. 때문에 forEach를 탈출하고 싶을 때는 return이 필요하다.

let hasC = false; 
let arr = ['a', 'b', 'c', 'd']; 

arr.forEach(el => { 
	If (el === 'c') { 
	hasC = true; 
	return; //
    } 
});

만약 forEach에서 현재 index를 알고 싶으면 두 번째 인자로 받을 수도 있다.

let idxOfC = -1; 
let arr = ['a', 'b', 'c', 'd']; 

arr.forEach((el, idx) => { 
	if (el === 'c') { 
	  idxOfC = idx; 
	  return; 
    } 
});
post-custom-banner

0개의 댓글