728x90

고차 함수(High-order Function)는 프로그래밍에서 매우 중요한 개념으로, 다른 함수를 인자로 받거나 함수를 반환하는 함수를 의미합니다. JavaScript는 함수형 프로그래밍 패러다임을 지원하며, 고차 함수를 사용하여 코드를 보다 유연하고 모듈화된 방식으로 작성할 수 있습니다. 이 글에서는 고차 함수의 정의, 사용 사례, JavaScript에서의 예제 및 장점을 자세히 설명하겠습니다.

고차 함수의 정의와 특징

정의

  • 함수를 인자로 받는 함수: 고차 함수는 다른 함수를 매개변수로 받을 수 있습니다.
  • 함수를 반환하는 함수: 고차 함수는 다른 함수를 반환할 수 있습니다.

특징

  1. 추상화 수준 증가: 고차 함수는 코드를 추상화하는 데 도움을 주어, 중복을 줄이고 코드의 재사용성을 높입니다.
  2. 코드의 유연성: 고차 함수는 다양한 동작을 매개변수로 전달받은 함수로 대체할 수 있어 코드의 유연성이 높습니다.
  3. 함수 조합: 여러 함수를 조합하여 복잡한 동작을 단순하게 구현할 수 있습니다.

JavaScript에서의 고차 함수 예제

JavaScript는 함수가 일급 객체(first-class citizens)로 취급되므로, 고차 함수를 쉽게 구현할 수 있습니다. 아래에서는 고차 함수의 몇 가지 대표적인 예제를 살펴보겠습니다.

예제 1: 함수를 인자로 받는 함수

배열 메소드: map

map 메소드는 배열의 각 요소에 대해 주어진 함수를 호출하여 새로운 배열을 반환합니다.

// 함수를 인자로 받는 고차 함수
function double(num) {
  return num * 2;
}

const numbers = [1, 2, 3, 4];
const doubledNumbers = numbers.map(double);

console.log(doubledNumbers); // [2, 4, 6, 8]
  • map 함수는 배열의 각 요소에 대해 double 함수를 호출하여 새로운 배열을 생성합니다. 이 예제에서 map은 고차 함수입니다.

forEach 메소드

forEach 메소드는 배열의 각 요소에 대해 주어진 함수를 실행합니다.

const numbers = [1, 2, 3, 4];

numbers.forEach((num) => {
  console.log(num * 2);
});

// 출력:
// 2
// 4
// 6
// 8
  • forEach는 각 배열 요소에 대해 콜백 함수를 실행합니다.

예제 2: 함수를 반환하는 함수

커링(Currying)

커링은 고차 함수의 일종으로, 여러 개의 인자를 받는 함수를 단일 인자를 받는 함수들의 체인으로 변환하는 기술입니다.

// 함수를 반환하는 고차 함수
function multiply(a) {
  return function(b) {
    return a * b;
  };
}

const multiplyByTwo = multiply(2);
console.log(multiplyByTwo(5)); // 10

const multiplyByThree = multiply(3);
console.log(multiplyByThree(5)); // 15
  • multiply 함수는 a를 인자로 받아 또 다른 함수를 반환합니다. 반환된 함수는 b를 인자로 받아 ab를 곱한 결과를 반환합니다. 이는 함수 조합을 통해 다양한 곱셈 함수를 생성할 수 있게 합니다.

함수 데코레이터

함수 데코레이터는 함수의 동작을 수정하거나 확장하기 위해 다른 함수를 감싸는 패턴입니다.

// 함수를 반환하는 고차 함수
function withLogging(func) {
  return function(...args) {
    console.log(`Calling ${func.name} with arguments:`, args);
    const result = func(...args);
    console.log(`Result:`, result);
    return result;
  };
}

function add(a, b) {
  return a + b;
}

const addWithLogging = withLogging(add);
addWithLogging(2, 3);
// 출력:
// Calling add with arguments: [ 2, 3 ]
// Result: 5
  • withLogging 함수는 주어진 함수를 감싸고, 호출 시 인자와 결과를 로그로 출력합니다. add 함수의 동작을 변경하지 않고도 부가적인 로깅 기능을 추가할 수 있습니다.

예제 3: 배열의 고차 함수

JavaScript에서는 배열을 다루기 위한 여러 고차 함수를 제공합니다.

filter 메소드

filter 메소드는 주어진 조건에 맞는 배열의 요소들만 포함하는 새로운 배열을 반환합니다.

const numbers = [1, 2, 3, 4, 5, 6];

// 짝수만 필터링
const evenNumbers = numbers.filter((num) => num % 2 === 0);

console.log(evenNumbers); // [2, 4, 6]
  • filter 함수는 배열의 각 요소에 대해 주어진 콜백 함수를 호출하여 조건에 맞는 요소들만 새로운 배열에 포함합니다.

reduce 메소드

reduce 메소드는 배열의 각 요소에 대해 주어진 함수를 호출하여 하나의 값을 반환합니다.

const numbers = [1, 2, 3, 4];

// 배열 요소의 합계 계산
const sum = numbers.reduce((accumulator, current) => accumulator + current, 0);

console.log(sum); // 10
  • reduce 함수는 배열의 각 요소에 대해 주어진 콜백 함수를 호출하여 누적된 결과를 계산합니다. 초기값(0)을 지정할 수 있으며, 누적된 결과를 반환합니다.

예제 4: 클로저와 고차 함수

고차 함수는 클로저를 활용하여 함수 내부의 변수를 유지할 수 있습니다.

function createCounter() {
  let count = 0;
  return function() {
    count += 1;
    return count;
  };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
  • createCounter 함수는 내부에 count 변수를 유지하는 클로저를 반환합니다. 반환된 함수는 호출될 때마다 count 값을 증가시키고 반환합니다.

고차 함수의 장점

1. 코드 재사용성

고차 함수는 코드를 재사용할 수 있도록 하여, 중복을 줄이고 코드의 모듈화를 촉진합니다. 예를 들어, 배열의 각 요소를 변환하거나 필터링하는 함수들은 다양한 조건과 로직을 매개변수로 전달받아 재사용할 수 있습니다.

2. 코드의 간결함

고차 함수는 코드를 간결하고 명확하게 만듭니다. 복잡한 동작을 간단한 함수 조합으로 구현할 수 있으며, 코드의 가독성을 향상시킵니다.

3. 유연한 기능 확장

고차 함수는 함수를 매개변수로 받아 다양한 동작을 수행할 수 있으므로, 기능을 유연하게 확장할 수 있습니다. 함수 데코레이터 패턴을 활용하여 기존 함수에 새로운 기능을 쉽게 추가할 수 있습니다.

4. 함수형 프로그래밍 지원

고차 함수는 함수형 프로그래밍의 핵심 요소로, 불변성과 순수 함수를 강조하며, 부작용을 최소화하고 코드를 예측 가능하게 만듭니다. 이는 특히 비동기 프로그래밍이나 병렬 처리에서 큰 장점을 제공합니다.

결론

고차 함수는 JavaScript의 강력한 기능으로, 코드를 보다 유연하고 모듈화된 방식으로 작성할 수 있게 합니다. 함수를 인자로 받거나 반환함으로써 코드를 추상화하고 재사용성을 높일 수 있습니다. JavaScript에서 고차 함수를 활용함으로써 가독성과 유지보수성을 향상시키고, 복잡한 동작을 간단하게 구현할 수 있습니다. 이는 특히 대규모 애플리케이션 개발과 함수형 프로그래밍을 지원하는 데 유용합니다.

728x90
반응형

+ Recent posts