여러 개의 인자를 받는 함수를 하나의 인자만 받는 함수로 나눠서 순차적으로 호출될 수 있게 체인 형태로 구성한 것.
아래에 커링 함수에 대해 정리.
- 커링 함수는 한번에 하나의 인자만을 전달하는 걸 원칙으로 함.
- 중간 과정상의 함수를 실행한 결과는 다음 인자를 받기 위해 대기.
- 마지막 인자가 전달 되기 전까지 원본 함수가 실행이 안 됨.
var curry = function(func) { return function(a) { return function(b) { return func(a, b); }; }; }; var getMaxWith10 = curry(Math.max)(10); console.log(getMaxWith10(8)); // 10 console.log(getMaxWith10(25)); // 25 var getMinWith10 = curry(Math.min)(10); console.log(getMinWith10(8)); // 8 console.log(getMinWith10(25)); // 10
변수
curry
에 커링 함수를 만들어서 할당한다.
getMaxWith10
은func
인자에Math.Max
를 넘기고, 처음return
되는 함수에 인자로10
을 넘겨서return
된 두 번째 인자를 받는 함수를 갖고있는다.
그리고console.log
에서b
에 인자8
을 넘겨서 최종적으로func(a, b)
, 즉Math.max(10, 8)
이 실행된 결과값이console
에 찍힌다.
나머지console
도 같은 원리로 작동한다.
위의 예제 처럼 커링 함수에 전달되는 인자가 적으면 괜찮지만 아래처럼 전달되는 인자가 많으면 코드도 길어지고, 가독성이 떨어질 수 있다.
var curry = function(func) { return function(a) { return function(b) { return function(c) { return function(d) { return function(e) { return func(a, b, c, d, e); }; }; }; }; }; };
그래서 화살표 함수로 바꾸면 코드도 줄고, 가독성도 올라간다.
var curry = func => a => b => c => d => e => func(a, b, c, d, e);
화살표 순서에 따라 왼쪽에서부터 차례로 인자를 넘겨주고, 마지막에 인자들을
func
에 담아 실행하는 걸로 생각하면 편하다.
당장 필요한 정보만 받아서 전달하고, 또 필요한 정보가 들어오면 전달하는 식으로 마지막 인자가 넘어갈 때까지 함수의 실행을 미루는 경우에 사용하면 유용하다.
이를 함수형 프로그래밍에서지연실행(lazy execution)
이라고 한다.
아래와 같은 예로 사용할 수 있다.
var getInformation = function(baseUrl) { return function(path) { return function(id) { return fetch(baseUrl + path + '/' + id); }; }; };
화살표 함수로도 표현.
var getInformation = baseUrl => path => id => fetch(baseUrl + path + '/' + id);
위에서 정의된 커링함수를 아래처럼 활용하면 된다.
var productUrl = 'http://productAddress.com/'; var getProduct = getInformation(productUrl); console.log(getProduct); // http://productAddress.com/ var getFruit = getProduct('fruit'); console.log(getFruit); // http://productAddress.com/fruit var fruit1 = getFruit(300); console.log(fruit1); // http://productAddress.com/fruit/300 var fruit2 = getFruit(400); console.log(fruit2); // http://productAddress.com/fruit/400
최근에는
Flux
아키텍쳐의 구현체 중 하나인Redux
의MiddleWare
에 사용된다.const logger = store => next => action => { console.log('dispatching', action); console.log('next state', store.getState()); return next(action); } const thunk = store => next => action => { return typeof action === 'function' ? action(dispatch, store.getState) : next(action); }
위 코드는
MiddleWare
인Logger
와Thunk
이다.
store
는 프로젝트 내에서 한 번 생성된 이후 바뀌지 않는 속성이고,dispatch
의 의미를 가지는next
도 마찬가지이다.
그러나action
은 매번 달라지기 때문에store
와next
를 미리 넘겨놓고,action
을 마지막 인자로 넘겨서action
이 바뀔 때마다 결과값이 다르게 표현한다.