티스토리 뷰
커링(Currying)
커링 은 함수 하나가 n개의 인자를 받는 과정을 n개의 단일 인자 함수열로 만드는 것 을 말하며, 특히 함수를 재사용 할 때 유용하게 쓰이는 JavaScript의 함수형 프로그래밍 기법 중 하나다.
잠시 왜 함수형 JavaScript를 쓰는지 간단히 설명하자면, 반복을 최소화하고 간결하게 작성할 수 있기 떄문에 직관적이고 테스트하기 쉬운 코드를 구현할 수 있다는 강점이 있다.
실제로 커링 함수를 어떻게 작성해야 하는지 알아보자.
function multiplyThree(x, y, z) {
console.log(x * y * z);
}
multiplyThree(4, 5, 2); // 40
위와 같이 인자 3개를 받아 곱셈을 처리하는 multiplyThree
함수가 있다.
이 함수를 앞에서 언급한 정의에 따라 커링을 하기 위해서는 x, y, z(n개의 인자)를 단일 인자 x, y, z를 가지는 함수로 나누면 된다. 즉, 커링할 원래 함수 와 인수를 유지하는 클로저 를 만드는 방식으로 커링함수를 만든다.
// 커링 함수
function multiplyThree(x) {
// 클로저로 생성된 공간
return function(y) {
return function(z) {
console.log(x * y * z);
};
};
}
multiplyThree(4)(5)(2); // 40
위 코드는 ES6의 화살표 함수 (arrow function)를 이용하면, 좀 더 간결하게 표현할 수 있다.
let multiplyThree = x => y => z => console.log(x * y * z); // 커링 함수
multiplyThree(4)(5)(2); // 40
앞에서 말했듯이 커링의 가장 큰 장점은 재사용성 이다.
재사용성이 높을 수록 생산성 도 좋아지고 유지보수 할 때도 유용하다.
일반함수
var fullName = function(last, first) {
console.log(last + first);
};
fullName('조', '다솜'); // 조다솜
fullName('조', '다영', ); // 조다영
fullName('조', '성준'); // 조성준
보통 일반 함수로는 성이 같은 여러 사람을 모두 출력할 때 위와 같이 출력할 것이다.
커링을 활용해 위와 같은 결과를 내면서 재사용성을 높여보면 다음과 같다.
커링함수
let fullName = last => first => console.log(last + first); // 커링 함수
let family = fullName('조'); // 클로저로 저장
family('다솜'); // 조다솜
family('다영'); // 조다영
family('성준'); // 조성준
첫 번째 인자에서 공통인 데이터를 클로저로 저장해두고, family
는 이름만 전달받아 성과 함께 출력해주는 새로운 함수로 만든다. 마찬가지로 다른 가족 이름을 출력하려면 fullName(last)
로 새로운 가족을 만들어 사용하면 된다.
간단한 예로 설명하다보니 재사용성에 대한 느낌이 오지 않아 예를 하나 더 들자면,
let sentence =
greeting => seperator => end => name =>
console.log(greeting + seperator + name + end);
let introduce = sentence('안녕하세요')('. ')('입니다.');
introduce('다솜'); // 안녕하세요. 다솜입니다.
let greet = sentence('안녕하세요')('? ')('씨.');
greet('다솜'); // 안녕하세요? 다솜씨.
let bye = sentence('안녕히가세요')(', ')('씨.');
bye('다솜'); // 안녕히가세요, 다솜씨.
위와 같이 sentence
라는 커링 함수 하나를 가지고 다양한 함수를 정의하고 사용할 수 있으며, 부분적으로 정의한 함수를 다시 정의해서 사용하는 패턴도 가능해 중복을 최소화할 수 있다.
전통적인 사용법
위에서는 ES6 문법을 사용해 쉽게 표현을 했지만 전통적으로 JavaScript는 기본적으로 커리함수를 지원하지 않는다. 그래서 화살표 함수 없이 커링을 구현하려면 코드가 매우 길어지게 된다. 그래서 전통적인 방법으로 구현하려면 Function.prototype 에 curry 메소드를 추가하는 방식으로 사용할 수 있다.
Function.prototype.curry = function() {
var slice = Array.prototype.slice;
var args = slice.apply(arguments);
var that = this;
return function() {
return that.apply(null, args.concat(slice.apply(arguments)));
};
}
var sum1 = sum.curry(1);
console.log(sum1(5)); // 6
console.log(sum1(3)); // 4
Reference
'JavaScript' 카테고리의 다른 글
이벤트 버블링(Bubbling)과 캡쳐링(Capturing) (0) | 2018.12.17 |
---|---|
메모이제이션 (Memoization) (0) | 2018.12.14 |
클로저 (Closure) (0) | 2018.12.09 |
호이스팅(Hoisting) , 실행 문맥(Execution Context), 스코프 체인(Scope Chain) (0) | 2018.12.09 |
스코프 (Scope) (0) | 2018.12.09 |
- Total
- Today
- Yesterday
- 클레리구스성당
- 디바스드림
- 리스본 대성당
- 비뉴베르드
- chama
- 클로저
- 헤갈레이라저택
- 문어스테이크
- 포르티망
- 버블링
- 베나길동굴
- 카보다로카
- JavaScript
- klm
- 스코프체인
- 신트라투어
- 포르투
- 알부페이라
- 수하물분실
- 이벤트
- 포르토
- 스코프
- 리스본
- 절벽마을
- 아제냐스두마르
- 에어프랑스
- 절벽트래킹
- 베나길
- tapabento
- vinhoverde
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |