[JavaScript] 커링

2023. 1. 12. 17:21·프로그래밍 언어/JavaScript

커링이란?

커링이란 f(a, b, c) 를 f(a)(b)(c) 와 같이 여러 개의 인수를 단일 프로세스로, 호출 가능한 함수를 다중 프로세스 형태로 변환할 수 있도록 하는 기술이다.

보통 자바스크립트에서 커링되어진 함수는 평소처럼 호출도 하고 만약에 인수들이 충분하지 않을 때는 partial 을 반환한다.

커링은 partial 을 쉽게 적용할 수 있도록 해준다.

커링을 사용하는 이유?

커링 함수를 사용하는 이유는 함수가 여러 개의 인자를 받을 때 특정 인자를 고정할 수 있습니다. 그로 인해 함수의 재사용성을 높일 수 있습니다.

// 커링을 사용한 함수
const currying = a => b => c => a * b * c;
console.log(currying(1)(2)(3)); // 6

// 인수 고정으로 재사용성 높이기
const alwaysMultiple2 = currying(1)(2);
console.log(alwaysMultiple2(3)); // 6

커링 구현

function curry(func) {
  return function curried(...args) {
    if (args.length >= func.length) {
      return func.apply(this, args);
    } else {
      return function pass(...args2) {
        return curried.apply(this, args.concat(args2));
      }
    }
  }
}

curry(func) 의 반환값은 curried 라는 래퍼이다. curried 라는 래퍼 안에는 두 개의 if 분기점이 있다.

if 조건을 충족하는 경우 즉 args 를 카운트한 갯수가 전달된 원래 함수 func 의 매개변수 개수와 같거나 크다면, 그대로 func 호출에 args 를 전달한다.

반면 if 조건을 충족하지 못하는 경우 아직 func 이 호출되지 않고 pass 라는 래퍼가 대신 반환된다. pass 래퍼함수가 curried 래퍼를 이전에 입력된 인수와 새로운 인수와 함께 다시 적용한다. 그 다음 새로운 curried 래퍼 호출에 인수가 충분하지 않으면 새로운 pass 래퍼를 반환하거나 최종적으로 func 결과를 반환한다.

커링 사용 예시 1)

function sum(a, b, c) {
  return a + b + c;
}

const curriedSum = curry(sum);

console.log(curriedSum(1, 2, 3)); // 6, 평소처럼 단일 callable 형식으로 호출
console.log(curriedSum(1)(2, 3)); // 6, 첫 번째 인수 커링
console.log(curriedSum(1)(2)(3)); // 6, 모두 커링

sum 함수는 인수가 세 개이므로 sum.length = 3 이다.

 

curriedSum(1)(2)(3) 이 호출되는 과정은 다음과 같다.

1. 첫번째 curriedSum(1) 을 호출할 때 1을 렉시컬 환경에 기억하고 curriedSum(1)이 pass 래퍼를 반환한다.

2. pass 래퍼가 (2)와 함께 호출된다. 이전의 인수인 (1)과 (2)를 연결해 curried(1, 2) 를 함께 호출한다. 인수의 개수는 2개로 아직 3보다 작기 때문에 curried 는 pass 래퍼를 반환한다.

3. pass 래퍼가 다시 (3)과 함께 호출된다. 다음 호출인 pass(3) 이 이전의 인수들인 (1, 2) 를 가져와 (3) 을 연결해 curried(1, 2, 3) 호출을 한다.

4. 인수의 개수는 3개로 sum 함수의 인수 3개와 같기 때문에 if 조건을 충족해 인수를 func 에 전달해 func(1, 2, 3) 호출한 후 최종적으로 결과값을 반환한다.

커링 사용 예시 2)

function log(logMessage = console.log, date, importance, text) {
  logMessage(`[${date.getHours()}:${date.getMinutes()}] [${importance}] ${text}`);
}

const curriedLog = curry(log);
// curriedLogByConsole 은 log의 첫 번째 인수가 고정된 partial 이 된다.
const curriedLogByConsole = curriedLog(console.log); 
// logNow 는 log의 첫 번째 인수, 두 번째 인수가 고정된 partial 이 된다.
const logNow = curriedLogByConsole(new Date());
// infoNow 는 log의 첫 번째 인수, 두 번째 인수, 세 번째 인수가 고정된 partial 이 된다.
const infoNow = logNow("INFO");

logNow("ERROR", "에러 발생"); // [HH:mm] ERROR 에러 발생
infoNow("메세지"); // [HH:mm] INFO 메세지

출처

https://ko.javascript.info/currying-partials 

https://my-first-programming.tistory.com/entry/%EC%BB%A4%EB%A7%81-Currying-%EC%9D%B4%EB%9E%80 

'프로그래밍 언어 > JavaScript' 카테고리의 다른 글

[JavaScript] iterable 객체  (0) 2023.01.11
[JavaScript] 예시를 통해 알아보는 this  (0) 2022.12.28
[JavaScript] 문자열 자르기 (substr, substring, slice)  (0) 2022.12.05
JavaScript 의 동작방식  (0) 2022.11.12
[JavaScript] 반복문  (0) 2022.11.05
'프로그래밍 언어/JavaScript' 카테고리의 다른 글
  • [JavaScript] iterable 객체
  • [JavaScript] 예시를 통해 알아보는 this
  • [JavaScript] 문자열 자르기 (substr, substring, slice)
  • JavaScript 의 동작방식
rondeveloper
rondeveloper
  • rondeveloper
    Ron's learning record
    rondeveloper
  • 전체
    오늘
    어제
    • 분류 전체보기 (99)
      • k8s (1)
      • AWS (1)
      • 리눅스 (3)
      • Docker (8)
      • 라이브러리 & 프레임워크 (14)
        • React (2)
        • NestJS (8)
        • Spring (0)
        • Django (3)
        • FastAPI (1)
      • 웹 (2)
        • Nginx (1)
      • 프로그래밍 언어 (29)
        • HTML (0)
        • CSS (0)
        • JavaScript (21)
        • Python (3)
        • Node.js (0)
        • TypeScript (4)
        • Java (1)
      • Today I learned (9)
      • 알고리즘 (9)
        • 백준 (0)
        • 프로그래머스 (8)
        • 개념 (1)
      • 티끌모아 태산 (5)
        • 하루에 영단어 하나씩 (5)
        • 독서 (0)
      • 시행착오 (3)
      • 데이터베이스 (2)
        • MySQL (0)
      • 컴퓨터 과학 (8)
        • 네트워크 (2)
        • 운영체제 (0)
        • 데이터베이스 (2)
        • 자료구조 (4)
      • 포트폴리오 (4)
        • JJINCAFE IN SEOUL (4)
        • CODEUNICORN (0)
      • 회고 (0)
      • CICD (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Til
    typescript
    Python
    django
    컨테이너
    프로그래머스
    스택
    네트워크
    모듈
    배열
    레벨2
    기초
    FastAPI
    nestjs
    조인
    도커
    redis
    javascript
    Kubernetes
    자바스크립트
    생활코딩
    쿠버네티스
    리눅스
    Kubectl
    mysql
    IP 주소
    코딩테스트
    typeorm
    iterable
    Docker
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
rondeveloper
[JavaScript] 커링
상단으로

티스토리툴바