728x90
반응형
커링
여러 인수를 갖는 함수를 단일 인수의 함수열로 바꾸는 것
함수형 프로그래밍을 사용하는 이유와 같이 부수 효과를 최소화 하고 동일한 입력 시 동일 출력을 나오게 하여
가독성과 유지보수를 용이하게 하기 위해 사용
일반적 커링 예시
// 커링 변환을 하는 curry(f) 함수 (일반 함수 ver)
function curry(f) {
return function(a) {
return function(b) {
return f(a, b);
};
};
}
// 커링 변환을 하는 curry(f) 함수 (화살표 함수 ver)
const curry = f => a => b => f(a, b);
// f에 전달된 함수
const sum = (a, b) => a + b;
const curriedSum = curry(sum);
console.log(curriedSum(1)(2)); // 3
- curry(func)는 function(a) 반환
- curriedSum(1) 호출 시, 1은 렉시컬 환경에 저장되고, function(b) 반환
- 2를 인자로 같는 function(b)가 호출되고 반환 값으로 f(a, b)가 호출 되면서
최종적으로 curry(f)의 인자 f로 전달된 sum(a, b)가 호출 되어 a + b의 값인 3이 반환됨
렉시컬 환경
스크립트, 실행중인 함수, 코드블록 등은 자신만의 렉시컬 환경을 갖는다
렉시컬 환경은 환경레코드, 외부렉시컬 환경으로 구성됨
환경 레코드
렉시컬 환경에서 모든 지역변수를 프로퍼티로 저장하고 있는 객체
this나 함수일 경우 매개변수도 포함된다.
function add(a, b) {
let name = 'Pete'
}
add()
// 환경레코드에 {name: 'Pete', a: undefined } 이런식으로 저장되어 있다.
외부 렉시컬 환경
현재 렉시컬 환경의 상위 렉시컬 환경, 스크립트는 최상위 렉시컬 환경으로
스크립트 내 함수나 코드블럭은 외부 렉시컬 환경으로 스크립트 렉시컬 환경을 참조
렉시컬 환경이 만들어질 때 Environment라는 숨김 프로퍼티가 생성된다
프로퍼티에 외부렉시컬 환경이 저장되어있으며
지역내에서 참조할 값이 없을 경우 프로퍼티에 접근하여 외부 렉시컬 환경을 참조하게된다
참조할 값이 없을 경우 최상위 렉시컬 환경까지 검색하게 되는 체이닝 과정이 일어남
그렇기 때문에 모든함수는 클로저라고 할 수 있다
// 함수는 선언이 아닌 실행 시 렉시컬 환경이 구성된다
function makeCounter() {
let count = 0;
return function() {
return count++;
};
}
// 함수를 표현식으로 사용하게 되면 변수에 저장되어 렉시컬 환경이 만들어지고,
// 중첩된 함수에서 외부 렉시컬 환경을 참조하므로 증가된 값이 반영됨
let counter = makeCounter();
console.log(counter()); // 0
console.log(counter()); // 1
console.log(counter()); // 2
console.log(makeConter()()); // 0
console.log(makeConter()()); // 0
console.log(makeConter()()); // 0
lodash를 사용한 커링
const _ = require('lodash');
const sum = (a, b) => a + b;
const curriedSum = _.curry(sum);
console.log(curriedSum(1)(2));
// lodash 라이브러리에 cuury() 함수가 정의되어 있음
객체를 다루는 커링 예시
커링을 적용하지 않은 코드
const todos = [
{ id: 3, content: 'HTML', completed: false },
{ id: 2, content: 'CSS', completed: true },
{ id: 1, content: 'Javascript', completed: false }
];
const getTodosIdArr = todos => todos.map(todo => todo.id);
const getTodosContentArr = todos => todos.map(todo => todo.content);
const getTodosCompletedArr = todos => todos.map(todo => todo.completed);
console.log(getTodosIdArr(todos)); // [ 3, 2, 1 ]
console.log(getTodosContentArr(todos)); // [ 'HTML', 'CSS', 'Javascript' ]
console.log(getTodosCompletedArr(todos)); // [ false, true, false ]
커링을 적용한 코드
const todos = [
{ id: 3, content: 'HTML', completed: false },
{ id: 2, content: 'CSS', completed: true },
{ id: 1, content: 'Javascript', completed: false }
];
const get = property => object => object[property];
const getId = get('id');
const getContent = get('content');
const getCompleted = get('completed');
const getTodosIdArr = todos => todos.map(getId);
const getTodosContentArr = todos => todos.map(getContent);
const getTodosCompletedArr = todos => todos.map(getCompleted);
console.log(getTodosIdArr(todos)); // [ 3, 2, 1 ]
console.log(getTodosContentArr(todos)); // [ 'HTML', 'CSS', 'Javascript' ]
console.log(getTodosCompletedArr(todos)); // [ false, true, false ]
참조:
커링
반응형
'프로그래밍 언어 > JS' 카테고리의 다른 글
JavaScript) 함수형과 절차형 프로그래밍 (0) | 2022.03.22 |
---|---|
JavaScipt) 클로저 (0) | 2022.03.18 |
JavaScript) MapReduce Model (0) | 2022.03.16 |
JavaScript) 내장 배열 고차함수 (0) | 2022.03.15 |
JavaScript) 일급 객체와 고차 함수 (0) | 2022.03.15 |
댓글