-
BEB Section 1 - 고차함수2nd of BEB/Codestates 2021. 11. 25. 02:15

Javascript에서는 함수를 아래와 같이 취급한다.
- 변수에 할당 가능하다.
- 다른 함수의 인자로 전달될 수 있다.
- 다른 함수의 결과로서 리턴 가능하다.
사실 난 아직도 얘네들이 매우 헷갈린다. 함수 안에 함수가 선언된다는 것 자체가 약간 내 머리 속에서는 이게 말이 되는거냐? 하고 박혀 있었는데 그 틀을 깨버린 Javascript..
일단 함수를 변수에 할당할 수 있기 때문에, 배열의 요소나 객체의 속성값으로도 저장할 수 있다. -> 사실 이거 무슨 말인지 모르겠어서 뒤에 말을 읽어봤는데
Data type 다루 듯 다룰 수 있다.
라는 말을 듣고 곧바로 이해.
본격적으로 들어가기 전에 다들 호이호이 하시길래 이게 뭔 말이야 했는데, 호이스팅(Hoisting)이었다.
- 호이스팅은 선언된 위치 상관없이 어디서든 함수 사용 가능
- 코드 실행 과정에서 함수 선언부를 코드 최상단으로 끌어올리는 것처럼 보이게 한다.
하지만 호이스팅에 의존하다보면 코드 유지 보수에 어려움이 있고, 디버깅 시 코드의 가독성이 매우 떨어진다.
const square = function (num){ return num * num; }; let output = square(7); console.log(output); // 49고차 함수
고차함수는 함수를 인자로 받을 수 있고, 그 형태를 그대로 리턴할 수 있는 함수이다. 맨 위에 Javascript의 함수 개념에 대해 간단히 설명했는데, 한 가지 더 말해주자면 변수를 따로 할당하지 않고 함수를 바로 사용할 수 있다. 다 그대로인데, 변수가 빠지고 고대로 동작한다는 뜻. 고차함수는 또한 커리 함수라고도 불린다.
여기서 콜백 함수가 쓰이게 되는데, 콜백 함수는 어떤 이벤트가 발생했거나 특정 지점에 도달했을 때 시스템이 호출되는 함수를 말한다. 일단 어떤 작업 하나가 완료가 돼야 호출되는 경우가 다분하다.
(여기서부턴 저만의 설명 방법입니다!)
- 다른 함수를 인자로 받는 경우
function double(num){ return num * 2; } function doubleNum(func, num){ return func(num); } let output = doubleNum(double, 4); console.log(output); // 8일단 함수가 2개 만들어졌고, doubleNum 함수에 func 콜백 함수가 선언되었다. 근데 doubleNum의 return 값을 보면 위에 double 함수랑 비슷한 형태다. 이렇게 우리는 double 함수는 doubleNum의 콜백 함수임을 알 수 있다.
- 함수를 리턴하는 경우
function adder(added){ return function(num){ return num + added; }; } let output = adder(5)(3); console.log(adder); // 8 const add3 = adder(3); let output = add3(2); console.log(output); // 5
생각할 때 그림을 오지게 그리는 편 adder 라는 함수 안에 또 함수가 호출되었는데 얘는 또 특이하게 이름 없이 그냥 return 값으로만 주었다. 난 로직을 이렇게 생각해냈다.
일단 adder 함수 안에 함수가 return된 건데 난 이걸 무시하고 일단 위 그림대로 이해했다. adder 안에는 num과 added가 있으니까 그 안에서 자기들끼리 노는데 안에 숫자의 순서만 잘 맞춰주자는 생각이었다. adder(5)(3)이 그 예시이다. adder의 5는 added의 값이다. 3은 num의 값이고, 하고 순서를 맞췄다. add3 같은 경우는 일단 adder(3)이니까 added에 3이 들어가겠다는 생각을 바로 했고, 그 다음 전달받은 값은 add3에 넣어주었다.
- 함수를 인자로 받고 함수를 리턴하는 경우
function double(num) { return num * 2; } function doubleAdder(added, func) { const doubled = func(added); return function (num) { return num + doubled; }; } doubleAdder(5, double)(3); // 13 const addTwice3 = doubleAdder(3, double); addTwice3(2); // 8
이해하기 개어려움. 이건 머리로 그림 그리다가 결국 애매하게 그림으로 표현해봤다. return 되는 값은 결국 num + doubled 이다. 근데 얘가 무조건 added라는 뜻은 아니고 임의로 그렇게 둔다는 뜻이다. 위에 doubleAdder 함수 때문이다. 그래서 밑에 doubleAdder(5, double)(3); 이걸 보면 added에 num을 대입한다. (콜백함수니까) 그럼 일단 5의 값을 저장하고 뒤에 double 함수로 다시 돌아가서 실행해야 하니까 받아온 5의 값을 2와 곱해준다. 일단 10의 값을 받아왔고 다시 doubleAdder 함수로 와 더하기 연산을 다시 진행한다. (10)(3)의 계산이니까 답은 13이 나온다.

고차함수에는 또 그 안에 쓸 수 있는 내장함수가 있다. 대표적으로 map, filter, reduce 가 있다.
- map
모든 요소에게 동일한 행동을 준 값에 대해 모두 반환하고, 기존에 있던 배열은 수정하지 않는다.
let arr = [1, 2, 3]; let result = arr.map(function(el) { return el * 2; }); console.log(result);arr 배열에 1, 2, 3이 순서대로 들어가 el에 순차적으로 들어간다. 그리고 각 숫자는 2씩 곱해져 다시 반환되고, 결과값이 [2, 4, 6] 으로 나오게 된다.
- filter
모든 요소 중 원하는 값만 필터링한 후 반환된다. 이 또한 기존에 있던 배열은 수정하지 않는다.
let arr = [1, 2, 3]; let result = arr.filter(function(el) { return el % 2 !==0 }); console.log(result);arr 배열에 1, 2, 3이 순서대로 들어가 el에 순차적으로 들어간다. 각 숫자는 return 문에 있는 조건 하에 true인 요소들만 뽑아 result로 나온다.
- reduce
배열을 하나의 값으로 만들어준다. 초기값을 정할 수 있고, 정해진 값이 없다면 배열의 맨 첫 번째 요소가 초기값이 된다. 초기값은 누적값의 기반이 된다.
let arr = [1, 2, 3]; let result = arr.reduce(function(acc, cur, idx) { acc + cur; return acc; }); console.log(result);초기값이 정해진 게 없기 때문에 1이 초기값이 된다. 그럼 acc에 1이 들어가고 그 다음 2를 이제 넣는 차례가 된다. 2는 cur 자리에 들어가게 되고 아까 acc에 1이 들어간 변수와 더해져서 누적값은 3이 된다. 아까 초기값은 누적값의 기반이 된다고 그랬으니 acc의 값은 3으로 변경된다.
'2nd of BEB > Codestates' 카테고리의 다른 글
BEB Section 1 - React 2 (2) 2021.12.01 BEB Section 1 - React 1 (1) 2021.11.30 BEB Section 1 - 웹개발 기초 : DOM (0) 2021.11.22 BEB Section 1 - 웹개발 기초 : CSS 레이아웃, Selector (0) 2021.11.22 BEB Section 1 - 웹개발 기초 : CLI(Command Line Interface) (1) 2021.11.21