JavaScript에서 커링
Source: Dev.to
커링이란?
커링은 여러 매개변수를 갖는 함수를 각각 하나의 인자를 받는 함수들의 연속으로 변환하는 함수형 프로그래밍 기법입니다:
f(a, b, c) → f(a)(b)(c)
이 기법은 클로저에 크게 의존합니다. 중첩된 각 함수는 이전 호출에서 전달된 인자에 접근할 수 있어, 모든 필요한 매개변수가 모일 때까지 값을 누적할 수 있습니다. 기대한 인자 개수가 모두 모이면 원래 함수가 실행되어 최종 결과를 반환합니다.
간단한 예시
function orderCoffee(type) {
return function (size) {
return function (milk) {
return `You selected ${type} ${size} with ${milk}`;
};
};
}
const orderOne = orderCoffee('Latte')('Medium')('Almond milk');
const orderTwo = orderCoffee('Americano')('Large')('No milk');
const orderThree = orderCoffee('Mocha')('Medium')('Almond milk');
console.log(orderOne); // You selected Latte Medium with Almond milk
console.log(orderTwo); // You selected Americano Large with No milk
console.log(orderThree); // You selected Mocha Medium with Almond milk
각 호출은 하나의 정보를 캡처하고, 다음 입력을 기다리는 새로운 함수를 반환합니다.
내부 동작 방식
-
첫 번째 호출 –
orderCoffee('Latte')
size를 기대하는 함수를 반환합니다.type('Latte')은 클로저를 통해 기억됩니다. -
두 번째 호출 –
orderCoffee('Latte')('Medium')
milk를 기대하는 함수를 반환합니다. 이제type과size가 모두 저장됩니다. -
세 번째 호출 –
orderCoffee('Latte')('Medium')('Almond milk')
세 개의 캡처된 값을 사용해 최종 문자열을 반환합니다.
화살표 함수 버전
화살표 함수를 사용하면 같은 패턴을 더 간결하게 표현할 수 있습니다:
const orderCoffee = (type) => (size) => (milk) =>
`You selected ${type} ${size} with ${milk}`;
const order = orderCoffee('Latte')('Medium')('Almond milk');
console.log(order); // You selected Latte Medium with Almond milk
단계별 분석
| 단계 | 표현식 | 반환값 |
|---|---|---|
| 1 | orderCoffee('Latte') | size를 기다리는 함수 |
| 2 | orderCoffee('Latte')('Medium') | milk를 기다리는 함수 |
| 3 | orderCoffee('Latte')('Medium')('Almond milk') | 최종 문자열 "You selected Latte Medium with Almond milk" |
커링을 사용하는 이유
- 재사용성 – 남은 인자를 다르게 전달하여 재사용할 수 있는 부분 적용 함수(partially applied function)를 만들 수 있습니다.
- 가독성 – 복잡한 호출을 더 작은, 의도를 명확히 드러내는 단계로 나눌 수 있습니다.
- 조합성 – 함수 합성이나 파이프라인 같은 다른 함수형 기법과 잘 어울립니다.
결론
커링은 다중 매개변수 함수를 단일 매개변수 함수들의 체인으로 분해하고, 클로저를 이용해 이전 인자를 기억합니다. 이 패턴은 코드를 단순화하고 재사용성을 높이며, JavaScript에서 함수형 프로그래밍 스타일에 자연스럽게 녹아들 수 있습니다.