JS - 커링 함수

이호현·2020년 12월 9일
2

JS

목록 보기
9/14

1. 커링 함수

1) 커링 함수란?

여러 개의 인자를 받는 함수를 하나의 인자만 받는 함수로 나눠서 순차적으로 호출될 수 있게 체인 형태로 구성한 것.
아래에 커링 함수에 대해 정리.

  1. 커링 함수는 한번에 하나의 인자만을 전달하는 걸 원칙으로 함.
  2. 중간 과정상의 함수를 실행한 결과는 다음 인자를 받기 위해 대기.
  3. 마지막 인자가 전달 되기 전까지 원본 함수가 실행이 안 됨.


2) 커링 함수 예

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에 커링 함수를 만들어서 할당한다.
getMaxWith10func인자에 Math.Max를 넘기고, 처음 return되는 함수에 인자로 10을 넘겨서 return된 두 번째 인자를 받는 함수를 갖고있는다.
그리고 console.log에서 b에 인자 8을 넘겨서 최종적으로 func(a, b), 즉 Math.max(10, 8)이 실행된 결과값이 console에 찍힌다.
나머지 console도 같은 원리로 작동한다.



3) 화살표 함수로 커링 함수 표현

위의 예제 처럼 커링 함수에 전달되는 인자가 적으면 괜찮지만 아래처럼 전달되는 인자가 많으면 코드도 길어지고, 가독성이 떨어질 수 있다.

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에 담아 실행하는 걸로 생각하면 편하다.





2. 커링 함수 활용

당장 필요한 정보만 받아서 전달하고, 또 필요한 정보가 들어오면 전달하는 식으로 마지막 인자가 넘어갈 때까지 함수의 실행을 미루는 경우에 사용하면 유용하다.
이를 함수형 프로그래밍에서 지연실행(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아키텍쳐의 구현체 중 하나인 ReduxMiddleWare에 사용된다.

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);
}

위 코드는 MiddleWareLoggerThunk이다.
store는 프로젝트 내에서 한 번 생성된 이후 바뀌지 않는 속성이고, dispatch의 의미를 가지는 next도 마찬가지이다.
그러나 action은 매번 달라지기 때문에 storenext를 미리 넘겨놓고, action을 마지막 인자로 넘겨서 action이 바뀔 때마다 결과값이 다르게 표현한다.

profile
평생 개발자로 살고싶습니다

0개의 댓글