[JS] 함수형 프로그래밍, map과 filter 그리고 reduce

Juno·2020년 12월 19일
1
post-thumbnail

😆들어가기

자바스크립트의 데이터 타입

📍기본형

  • 숫자, boolean, null, undeifned, 등

📍참조형

  • 배열, 객체, 함수, 등

기본형

기본형은 값을 복사한다!

var x = 100;    // 기본형 
var y = x;      // 값을 새 변수에 복사
x = 99;         // x의 값을 변경
console.log(y); // 100, y의 값은 변경되지 않음

참조형

참조형은 주솟값을 복사한다!

var x = {count: 100}; // 참조형인 객체로 데이터를 선언
var y = x;            // 새 변수에 복사
x.count = 99;         // 참조 타입 데이터를 변경

console.log(y.count); // 99, 'x'와 'y'는 동일한 참조를 담고 있음, 동일한 객체를 가르킴

참조형은 복사시, 같은 주소값을 가지게 된다.

var array1 = [ 0,1,2,3 ];
var array2 = array1;
array2.push(4);

console.log(array1 === array2);

array2 = array1 와 같이 대입을 통해 복사를 한 뒤, array2push(4) 를 하였지만,

array1array2와 같이 [0,1,2,3,4]의 배열을 갖게 된다.

TMI에 나올 불변성에 대한 이해를 돕기 위해 먼저 설명했습니다!

😃 자바스크립트 메서드 map과 filter

map MDN 공식 문서

filter MDN 공식 문서

MDN 이란

파이어폭스 브라우저를 개발한 모질라 재단에서 만든 Mozilla Developer Center의 줄임말로, 웹 표준과 모질라 프로젝트에 대한 개발 문서들이 담긴 모질라의 공식 웹사이트이다.

✅ MDN 웹 문서는 개발자 커뮤니티가 관리하며 HTML CSS Javascript 웹 API등 다양한 웹 주제의 개발 자료를 담고 있다!

✅ 공식문서라고 생각하면 됨!

map

map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다.

const array1 = [1,4,9,16];
const map1 = array1.map(x => x*2);

console.log(map1); // [2,8,16,32]

구문

Array.prototype.map(callback,[, thisArg])
// callback: function(currentValue, index, array) 

콜백(callback)함수란?

  • 다른 코드의 인자로 넘겨주는 함수
  • 콜백함수를 넘겨받은 코드는 이 콜백함수를 필요에 따라 적절한 시점에 실행할 것
  • 콜백함수를 인자를 통해 넘겨주면서 제어권을 ****넘겨줬다고 생각하기!

예시) 알람을 설정한 준호, 그러지 못한 준호...

알람을 설정하지 못한 준호는, 불안함에 떨며 계속 일어나서 시계를 확인함

알람을 설정한 준호는, 특정 시점에 확실하게 알람이 울릴 것을 확신하고 푹 잘수 있다!

다시 돌아와서

function(num) 이 콜백함수가 되고, map 함수에 의해 map을 호출하는 주체인 numbers의 각 요소에 대해 콜백함수 function(num)을 수행하여 새로운 배열 doubles 를 만들게 된다!

var numbers = [1,4,9]
var doubles = numbers.map(function(num){
	return num * 2;
});
// doubles[2,8,18]
// numbers[1,4,9]
// console.log(numbers === doubles) result : false

// 화살표 함수를 사용하면 다음과 같이 쓸 수 있다.
var doubles = numbers.map((num)=> num * 2 );

✔️ 정리하자면,

  1. map에게 제어권을 넘겼고,
  2. map이 배열의 각 요소에 대해 접근할 때 콜백함수를 실행시킨 후
  3. 결과값을 새로운 배열로 반환한다
// (참고) index를 사용할 수 있다.
var doubles = numbers.map(function(num),index{
	console.log(num,index);
	return num * 2;
});
// result : 1, 0
// 4, 1
// 9, 2
// doubles [2,8,18]

filter

filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);

map과 같은 개념으로 사용할 수 있고, 함수의 이름 그대로 필터링 에 적합하다!

위의 예시에선, 배열의 요소 중 word의 길이가 6이상인 단어들을 삭제하였다.

주로 요소의 삭제를 할때 사용한다!

ex) to-do-list 에서 실행한 일을 지울 때


😅 TMI

react에서 map과 filter 함수를 사용하는 이유

react 성능 최적화를 위해서 참조형 데이터(배열)의 불변성을 유지시키기 위함

(기존의 값은 건드리지 않아야 한다는 뜻)

react의 state를 수정할 때, pop() 이나 push() 를 사용하여 내부의 값을 직접적으로 수정하면

배열 자체를 직접 수정하게 되므로 불변성 유지가 되지 않는다.

그 대신, 기존의 배열에 기반하여 새 배열을 반환할 수 있는 map() 이나 filter()를 이용하는 것이다!

그래서 왜??

react.js 컴포넌트에선 특정한 상황에 "리렌더링"을 하게 되는데

(바뀐 state나 props에 대하여 virtual dom을 바뀐 부분만 새로 그리는 행위, 즉 데이터가 바뀐 부분만 새로 갱신하는 작업이라고 생각하면 됨)

  1. state의 값이 변경되었을 때
  2. 상위 컴포넌트(부모)에서 전달받은 props의 값이 변경되었을 때

만약 기존값에 push() 를 이용하여 추가하는 경우엔,

var ary1 = [1,2,3]
var ary2 = ary1
ary2.push(2)

// 이와 같이 배열은 분명히 바뀌었지만
// ary1 === ary2 이므로 리액트에선 리렌더가 되지 않는다!

참조하는 객체의 주소가 같기 때문에 state가 바뀜을 인지하지 못하여 원하는 때에 리렌더링이 되지 않으므로 개발자의 의도와 다르게 동작하게 된다.

profile
사실은 내가 보려고 기록한 것 😆

0개의 댓글