고차함수란, 함수를 인자로 전달받거나 함수를 결과로 반환하는 함수를 뜻한다.
고차 함수는 인자로 받은 함수를 필요한 시점에 호출하거나, 클로저를 생성하여 반환한다.
함수를 인수로 전달하고 반환할 수 있는 이유는 자바스크립트 함수는 일급 객체이기 때문이다.
const square = function (num) {
return num * num;
};
// 변수 square에는 함수가 할당되어 있으므로 (일급 객체),
// 함수 호출 연산자 '()'를 사용할 수 있다.
output = square(7);
console.log(output); // --> 49
'함수를 리턴하는 함수' 를 고안해 낸 논리학자 하스켈 커리(Haskell Curry)의 이름을 따 커링함수라고 한다.
다른 함수의 전달인자로 전달되는 함수를 콜백 함수라고 한다.
보통 어떤 작업이 완료되었을 때 호출하는 경우가 많으며, 콜백 함수를 전달받은 고차함수는 함수 내부에서 이 콜백 함수를 호출할 수 있다.
또 조건에 따라 콜백함수의 실행 여부를 결정할 수 있기 때문에 아예 호출하지 않거나 여러번 실행도 가능하다.
function double(num) {
return num * 2;
}
function doubleNum(func, num) {
return func(num);
}
함수 doubleNum
의 첫번째 인자 func
에 함수가 들어올 경우 doubleNum
의 콜백 함수가 된다.
doubleNum(double, 4) // 8
JS에는 기본적으로 내장된 고차 함수가 있는데, 배열 메서드들 중 일부가 대표적인 고차함수에 해당한다.
filter 메서드는 배열의 요소 중 특정 조건을 만족하는 요소를 걸러내는 메서드이다.
짝수를 걸러내거나, 5보다 큰 수를 걸러내는 등 '필터' 기능을 한다.
let arr = [1, 2, 3, 4]
arr.filter(x => (x < 3)) // [1, 2]
map 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다. 하나의 데이터를 다른 데이터로 매핑(mapping) 할 때 사용한다.
const arr = [1, 4, 9, 16];
arr.map(x => x * 2); // [2, 8, 18, 32]
map은 callback 함수를 각각의 요소에 대해 한번씩 순서대로 불러 그 함수의 반환값으로 새로운 배열을 만든다.
callback
함수는 undefined
를 포함한 배열 값이 들어있는 인덱스만 호출하기 때문에, 값이 삭제되거나 아직 값이 할당/정의되지 않은 인덱스는 호출되지 않는다.
reduce 메서드는 배열의 각 요소에 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환한다. 하나의 결과값이 키포인트!
const arr = [1, 2, 3, 4]
arr.reduce((acc, cur) => (acc+cur)) // 10
리듀서 함수의 반환 값은 누산기에 할당되고, 누산기는 순회중 유지되므로 최종 결과는 하나의 값이 된다.
2차원 배열을 1차원 배열로 합칠때도 유용하게 쓰였다!
const arr1 = [[1, 2, 3, 4, 5], [10, 20, 30, 40, 50]] // 2차원 배열
const arr2 = arr1.reduce((acc, cur) => acc.concat(cur))
// arr2 = [1, 2, 3, 4, 5, 10, 20, 30, 40, 50]
누산기라는 표현이 쓰였듯, 한번에 모든 요소를 계산하는 것이 아닌
위 그림과 같이 더한 요소가 누적되고 그 다음값을 더하고, 또 그 더한 값이 누적되고 다음 값이 더해지는 방식이다.