JS

JS 커링

JUNG_EV 2024. 4. 11. 15:32

커링(Currying)은 함수형 프로그래밍에서 자주 사용되는 고급 기술입니다. 이 기술은 여러 개의 인자를 받는 함수를 각각의 인자가 호출 가능한 단계로 변환하여, 함수의 재사용성을 높이고 사이드 이펙트를 최소화하는 데 도움을 줍니다.

커링은 순수 함수의 원칙을 따르며, 동일한 입력에 대해 항상 동일한 출력을 반환합니다. 또한, 클로저의 개념을 활용하여 작동합니다.

일반 함수와 화살표 함수를 이용한 커링

일반 함수 예제

 

const sum = (a, b) => a + b;
const multy = (a, b) => a * b;

function printCurry(fn) {
  console.log(arguments); // fn
  return function(a) {
    console.log(arguments, fn); // a, fn
    return function(b) {
      console.log(arguments, a); // b, a
      return fn(a, b);
    };
  };
}

printCurry(sum)(1)(2); // 3
printCurry(multy)(2)(3); // 6

 

화살표 함수 예제

 

const sum = (a, b) => a + b;
const multy = (a, b) => a * b;

const printCurry = fn => a => b => fn(a, b);

printCurry(sum)(1)(2); // 3
printCurry(multy)(2)(3); // 6
 

 

재사용성

커링은 클래스와 비슷한 방식으로 작동하여, 인자를 초기에 주면 그 값이 렉시컬 스코프에 저장되어 이후에 사용할 함수에 고정 값으로 사용됩니다.

 

커링을 이용한 값 고정

 

const sum = a => b => a + b;

const sumWithOne = sum(1);

sumWithOne(3); // 4

 

 

클래스를 이용한 값 고정

 

class MathClass {
  constructor(a) {
    this.a = a;
  }

  sum(b) {
    return this.a + b;
  }
  
  multy(b) {
    return this.a * b;
  }
}

const sumWithOne = new MathClass(1);
sumWithOne.sum(3); // 4

 

 


동적 인자 처리

인자의 개수가 불확실한 상황에서 커링을 사용하는 방법은 다음과 같습니다.

 

function sum(num) {
  let result = num;
  return function adder(nextNum) {
    if (nextNum === undefined) {
      return result;
    }
    result += nextNum;
    return adder;
  };
}

sum(1)(2)(); // 3
sum(2)(10)(2)(12)(); // 26
 

이 방식은 렉시컬 환경과 재귀를 이용하여, 인자가 더 이상 제공되지 않을 때까지 계속해서 함수를 호출하고 결과를 누적합니다.

논커리와 커리의 차이점

  • 논커리(Non-Currying): 일반 함수에서 사용되며, 매개변수가 부족해도 함수를 실행할 수 있습니다.
  • 커리(Currying): 인자들을 단계별로 받아 처리하고, 모든 매개변수를 받을 때까지 실행을 보류합니다.

커링은 함수의 재사용성을 높이고, 더 세분화된 함수를 생성할 수 있게 해주어, 함수형 프로그래밍에서 매우 유용한 기술입니다.