고차 함수 (Higher-Order Functions)
자바스크립트(JavaScript)에서 고차 함수(Higher-Order Functions)는 함수(Function)를 다루는 중요한 기법 중 하나이다. 함수를 인자로 받거나 함수를 반환하는 함수를 의미하며, 이를 통해 코드의 유연성과 재사용성을 높일 수 있다. 고차 함수(Higher-Order Functions)의 정의, 구현 방법, 일반 함수와의 차이점, 그리고 사용 사례를 예제를 통해 확인한다.
고차 함수(Higher-Order Functions)는 자바스크립트(JavaScript)가 함수를 일급 객체(First-Class Citizen)로 취급하는 특성을 활용한다. 배열(Array) 메서드나 콜백(Callback) 함수에서 자주 등장하며, 함수형 프로그래밍(Functional Programming)과도 밀접한 연관이 있다. 고차 함수(Higher-Order Functions)를 통해 코드의 구조를 개선하고 로직을 효율적으로 분리할 수 있다.
고차 함수(Higher-Order Functions)란 무엇인가?
고차 함수(Higher-Order Functions)는 함수(Function)를 인자로 받거나 반환하는 함수를 말한다. 자바스크립트(JavaScript)에서 함수는 값처럼 다룰 수 있는 일급 객체이므로, 이러한 방식이 가능하다. 기본적인 예제를 통해 이를 확인한다:
function sayHello(callback) {
callback("철수");
}
sayHello(name => console.log(`안녕, ${name}!`)); // 안녕, 철수!
위 코드에서 sayHello
함수는 콜백 함수(Callback Function)를 인자로 받아 실행한다. 함수를 반환하는 경우도 있다:
function multiplyBy(factor) {
return x => x * factor;
}
const double = multiplyBy(2);
console.log(double(5)); // 10
multiplyBy
는 숫자를 인자로 받아 곱셈을 수행하는 함수를 반환한다. 이를 통해 double
과 같은 새로운 함수를 생성할 수 있다. 고차 함수(Higher-Order Functions)는 함수를 래핑하거나 조합하는 데 유용하다.
자바스크립트(JavaScript)에서 고차 함수(Higher-Order Functions)는 이미 익숙한 배열 메서드에서도 사용된다. 예를 들어 map
, filter
, reduce
는 모두 고차 함수의 대표적인 사례이다:
const numbers = [1, 2, 3];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6]
고차 함수(Higher-Order Functions)는 코드의 가독성을 높이고, 로직을 분리하여 관리하기 쉽게 만든다.
고차 함수(Higher-Order Functions)의 구현 방법
고차 함수(Higher-Order Functions)는 두 가지 주요 방식으로 구현된다. 함수를 인자로 받는 방식과 함수를 반환하는 방식이다.
1. 함수를 인자로 받기
콜백(Callback)을 인자로 받아 작업을 처리하는 방식이다.
function repeat(n, action) {
for (let i = 0; i < n; i++) {
action(i);
}
}
repeat(3, i => console.log(`반복 ${i}`)); // 반복 0, 반복 1, 반복 2
조건에 따라 동작을 실행하는 예제도 있다:
function unless(condition, fn) {
if (!condition) fn();
}
unless(2 > 3, () => console.log("거짓이다")); // 거짓이다
2. 함수를 반환하기
새로운 함수를 생성하여 반환하는 방식이다.
function addOffset(offset) {
return x => x + offset;
}
const addTen = addOffset(10);
console.log(addTen(5)); // 15
여러 요소를 조합하는 예제도 가능하다:
function wrapWith(prefix, suffix) {
return text => `${prefix}${text}${suffix}`;
}
const boldText = wrapWith("", "");
console.log(boldText("강조")); // 강조
고차 함수(Higher-Order Functions)와 일반 함수의 차이점
고차 함수(Higher-Order Functions)는 일반 함수와 사용 방식 및 설계 측면에서 차이가 있다.
1. 함수 처리 방식
- 일반 함수: 입력을 받아 결과를 반환한다.
function add(a, b) {
return a + b;
}
console.log(add(2, 3)); // 5
- 고차 함수: 함수를 인자로 받아 처리하거나 반환한다.
function addWith(fn) {
return (a, b) => fn(a) + fn(b);
}
const addSquares = addWith(x => x * x);
console.log(addSquares(2, 3)); // 13 (4 + 9)
2. 유연성
- 일반 함수: 고정된 로직을 수행한다.
function doubleArray(arr) {
return arr.map(x => x * 2);
}
- 고차 함수: 로직을 동적으로 변경할 수 있다.
function transformArray(fn) {
return arr => arr.map(fn);
}
const tripleArray = transformArray(x => x * 3);
console.log(tripleArray([1, 2, 3])); // [3, 6, 9]
사용 사례
고차 함수(Higher-Order Functions)의 활용 사례를 예제를 통해 확인한다.
1. 배열 가공
const scores = [85, 92, 78, 95];
const adjustScore = adjust => scores.map(score => score + adjust);
console.log(adjustScore(5)); // [90, 97, 83, 100]
2. 이벤트 처리
function logEvent(type) {
return e => console.log(`${type}: ${e.target.value}`);
}
document.querySelector("input").addEventListener("input", logEvent("입력"));
3. 타이머 조작
function delay(fn, ms) {
return (...args) => setTimeout(() => fn(...args), ms);
}
const delayedLog = delay(console.log, 1000);
delayedLog("1초 후 출력"); // 1초 후 출력
4. 로깅 래퍼
function withLogging(fn) {
return (...args) => {
console.log(`호출: ${args}`);
return fn(...args);
};
}
const logAdd = withLogging((a, b) => a + b);
console.log(logAdd(2, 3)); // 호출: 2,3 → 5
5. 조건 필터
function filterBy(fn) {
return arr => arr.filter(fn);
}
const evenNumbers = filterBy(x => x % 2 === 0);
console.log(evenNumbers([1, 2, 3, 4])); // [2, 4]
6. 함수 조합
const compose = (f, g) => x => f(g(x));
const addOne = x => x + 1;
const square = x => x * x;
const addThenSquare = compose(square, addOne);
console.log(addThenSquare(3)); // 16 ( (3 + 1)^2 )
7. 비동기 처리
function retry(fn, times) {
return async (...args) => {
for (let i = 0; i < times; i++) {
try {
return await fn(...args);
} catch (e) {
if (i === times - 1) throw e;
}
}
};
}
const fetchWithRetry = retry(fetch, 3);
fetchWithRetry("https://api.example.com").then(res => res.json());
8. 데이터 변환
function formatData(formatter) {
return data => data.map(formatter);
}
const toUpper = formatData(str => str.toUpperCase());
console.log(toUpper(["hi", "hello"])); // ["HI", "HELLO"]
성능과 한계
장점
- 유연성: 로직을 동적으로 변경할 수 있다.
- 재사용성: 함수를 조합하여 새로운 기능을 생성한다.
- 가독성: 코드가 간결해지고 로직이 분리된다.
한계
- 복잡성: 과도한 중첩은 가독성을 떨어뜨릴 수 있다.
- 성능: 함수 호출이 증가하면 실행 속도가 느려질 수 있다.
간단한 작업에는 고차 함수를 활용하고, 복잡한 로직은 일반 함수로 처리하는 것이 적합하다.
마무리
고차 함수(Higher-Order Functions)는 자바스크립트(JavaScript)에서 함수를 다루는 도구이고 사용 사례를 통해 그 유용성을 확인했다.
'코딩 공부 > 자바스크립트' 카테고리의 다른 글
34. 자바스크립트 프로미스 (Promises) (1) | 2025.03.07 |
---|---|
33. 자바스크립트 클로저 (Closures) (1) | 2025.03.07 |
31. 자바스크립트 재귀 함수 (Recursive Functions) (0) | 2025.03.06 |
30. 자바스크립트 메모이제이션 (Memoization) (1) | 2025.03.06 |
29. 자바스크립트 커링 (Currying) (1) | 2025.03.05 |