Higher-Order Function
고차 함수
함수를 인자로 받거나 반환하는 함수. map, filter, reduce가 대표적.
고차 함수
함수를 인자로 받거나 반환하는 함수. map, filter, reduce가 대표적.
고차 함수(Higher-Order Function)는 함수를 인자로 받거나 함수를 반환하는 함수를 말합니다. 이 개념은 함수형 프로그래밍의 핵심 원리로, 함수를 일급 객체(First-Class Citizen)로 취급하는 언어에서 자연스럽게 구현됩니다. JavaScript, Python, Haskell 등 현대 프로그래밍 언어 대부분이 고차 함수를 지원합니다.
가장 대표적인 고차 함수로는 map, filter, reduce가 있습니다. map은 배열의 각 요소에 함수를 적용하여 새 배열을 만들고, filter는 조건을 만족하는 요소만 추출하며, reduce는 배열을 하나의 값으로 축약합니다. 이들은 for 루프를 대체하여 코드를 더 선언적이고 읽기 쉽게 만들어줍니다.
고차 함수의 핵심 장점은 추상화와 재사용성입니다. 반복되는 패턴을 함수로 추상화하면 코드 중복을 줄이고, 함수를 조합하여 복잡한 로직을 구성할 수 있습니다. 또한 부수 효과(Side Effect)를 줄여 테스트와 디버깅이 용이해집니다.
실무에서 고차 함수는 이벤트 핸들러 등록, 콜백 패턴, 미들웨어 구현, 데코레이터 패턴 등 다양한 곳에서 활용됩니다. React의 고차 컴포넌트(HOC), Redux의 미들웨어, Express의 라우터 체인 모두 고차 함수의 원리를 응용한 것입니다. 모던 프론트엔드 개발에서는 필수적으로 이해해야 하는 개념입니다.
// 1. 기본 고차 함수: 함수를 인자로 받는 경우
const numbers = [1, 2, 3, 4, 5];
// map: 각 요소를 변환
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// filter: 조건에 맞는 요소만 추출
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4]
// reduce: 배열을 하나의 값으로 축약
const sum = numbers.reduce((acc, n) => acc + n, 0);
console.log(sum); // 15
// 2. 함수를 반환하는 고차 함수
function multiplier(factor) {
return function(number) {
return number * factor;
};
}
const double = multiplier(2);
const triple = multiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
// 3. 실용적인 예제: 커링(Currying)
const curry = (fn) => {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
}
return (...nextArgs) => curried(...args, ...nextArgs);
};
};
const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 6
console.log(curriedAdd(1, 2)(3)); // 6
console.log(curriedAdd(1)(2, 3)); // 6
// 4. 함수 합성(Composition)
const compose = (...fns) => (x) =>
fns.reduceRight((acc, fn) => fn(acc), x);
const addOne = x => x + 1;
const square = x => x * x;
const toString = x => `Result: ${x}`;
const compute = compose(toString, square, addOne);
console.log(compute(4)); // "Result: 25" (4+1=5, 5^2=25)
"이 데이터 변환 로직은 map과 filter를 체이닝해서 처리하면 될 것 같아요. for 루프보다 가독성도 좋고, 중간 결과를 확인하기도 편합니다. 성능이 중요한 부분은 reduce로 한 번에 처리하는 것도 고려해보죠."
"고차 함수는 함수를 인자로 받거나 반환하는 함수입니다. 대표적으로 Array의 map, filter, reduce가 있고요. 이를 활용하면 함수 합성이나 커링 같은 함수형 프로그래밍 패턴을 구현할 수 있습니다. React의 HOC도 고차 함수의 응용입니다."
"여기 forEach에서 외부 변수를 수정하는 대신 reduce를 사용하면 어떨까요? 부수 효과 없이 결과를 만들 수 있어서 디버깅도 쉽고, 함수 단위로 테스트 작성하기도 좋습니다."
map은 변환용, filter는 추출용입니다. map에서 undefined를 반환하면 배열 길이가 유지되고, filter에서 원소를 변환하면 의도치 않은 결과가 나옵니다. 목적에 맞는 메서드를 선택하세요.
map().filter().map() 처럼 여러 번 순회하면 대용량 데이터에서 성능 문제가 생깁니다. reduce로 한 번에 처리하거나, 꼭 필요한 경우만 체이닝하세요.
일반 함수를 콜백으로 전달하면 this가 달라집니다. 화살표 함수를 사용하거나, bind()로 명시적 바인딩하세요. 클래스 메서드를 콜백으로 넘길 때 특히 주의가 필요합니다.
고차 함수에 전달하는 콜백은 작고 순수하게 만드세요. 재사용이 가능하고, 테스트하기 쉬우며, 함수 합성으로 복잡한 로직을 구성할 수 있습니다.