커링 패턴
커링(currying) 패턴은 함수를 설계할 때 인자 전체를 넘겨서 호출할 수도 있지만, 일부 인자는 먼저 입력해두고 나머지만 입력받을 수 있도록 새로운 함수를 만드는 패턴을 의미합니다. 커링 패턴은 하나의 공용 함수가 있는 경우 이를 세부적인 기능을 하는 함수로 나누고 싶을 때 유용합니다.
적용예시1. 합을 구하는 기본 함수
makeAdder() 함수로 인자를 하나 받은 뒤, 나머지 인자를 하나 받는 함수를 반환한다. 여기서 반환된 함수가 호출되면 클로저로 저장되어 있던 x와 새로 입력되어 들어온 y를 sum() 함수의 인자로 넘긴다. 그 결과 sum(x,y)의 결과가 나온다.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="userInfo"></div>
<script>
(function () {
function sum(x, y) {
return x + y;
}
let makeAdder = function (x) {
return function (y) {
return sum(x, y);
};
};
console.info("커링 패턴 적용 X")
console.log(sum(4,1)); // === 5
console.log(sum(4,5)); // === 9
console.info("커링 패턴 적용 O")
let adderFour = makeAdder(4);
console.log(adderFour(1)); // === 5
console.log(adderFour(5)); // === 9
}());
</script>
</body>
</html>
적용예시2. Function.prototype에 커링 패턴 함수 추가
자바스크립트는auguments 객체와 apply() 함수로 가변 인자들을 유동적으로 변경하고 클로저를 통해 먼저 넘어온 데이터 값에 대한 보관까지 쉽게 할 수 있어 아래와 같이 구현할 수 있습니다.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="userInfo"></div>
<script>
(function () {
Function.prototype.curry = function() {
if (arguments.length<1) {
return this;
}
let _this = this,
args = Array.prototype.slice.apply(arguments);
return function() {
return _this.apply(this, args.concat(Array.prototype.slice.apply(arguments)));
}
}
function sum(x, y) {
return x + y;
}
let adderFourCurry = sum.curry(4);
console.log(adderFourCurry(5)); // === 9
console.log(adderFourCurry(10)); // === 14
function sum4(x, y, z, w) {
return x + y + z + w;
}
let adderCurry = sum4.curry(5,1);
console.log(adderCurry(2,3)); // === 11
}());
</script>
</body>
</html>
적용예시3. 커링 패턴을 이용한 단위 변환
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="userInfo"></div>
<script>
(function () {
Function.prototype.curry = function() {
if (arguments.length<1) {
return this;
}
let _this = this,
args = Array.prototype.slice.apply(arguments);
return function() {
return _this.apply(this, args.concat(Array.prototype.slice.apply(arguments)));
}
}
function unitConvert(fromUnit, toUnit, factor, input) {
return `${input} ${fromUnit} === ${(input*factor).toFixed(2)} ${toUnit}`;
}
let cm2inch = unitConvert.curry('cm', 'inch', 0.393701),
metersquare2pyoung = unitConvert.curry('m^2', 'pyoung', 0.3025),
kg2lb = unitConvert.curry('kg', 'lb', 2.204623),
kmph2mph = unitConvert.curry('km/h', 'mph', 0.621371);
console.log(cm2inch(10));
console.log(metersquare2pyoung(30));
console.log(kg2lb(50));
console.log(kmph2mph(100));
//==>>
// 10 cm === 3.94 inch
// 30 m^2 === 9.07 pyoung
// 50 kg === 110.23 lb
// 100 km/h === 62.14 mph
}());
</script>
</body>
</html>
적용예시4. XMLHttpRequest를 위한 커링 패턴 응용
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="userInfo"></div>
<script>
(function () {
Function.prototype.curry = function() {
if (arguments.length<1) {
return this;
}
let _this = this,
args = Array.prototype.slice.apply(arguments);
return function() {
return _this.apply(this, args.concat(Array.prototype.slice.apply(arguments)));
}
}
function ajax(method, url, data, callback) {
let xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (xhr.status === 200) {
callback.call(this, xhr.responseText);
}
}
xhr.send(data);
}
let ajaxGet = ajax.curry("GET"),
ajaxPost = ajax.curry("POST"),
ajaxPut = ajax.curry("PUT"),
ajaxDelete = ajax.curry("DELETE");
ajaxGet("/data", null, function (responseText) {
console.log(responseText);
});
}());
</script>
</body>
</html>
#
참고도서 : 속깊은 자바스크립트
이전글 :
2021/02/10 - [Study Note/Javascript] - javascript #디자인패턴 - 폼 검증을 위한 데커레이터 패턴(decorator pattern)
2021/02/10 - [Study Note/Javascript] - javascript #디자인패턴 - 객체 기반 데커레이터 패턴(decorator pattern)
2021/02/10 - [Study Note/Javascript] - javascript #디자인패턴 - 함수 기반 데커레이터 패턴(decorator pattern)
2021/02/10 - [Study Note/Javascript] - javascript #디자인패턴 - Init-time branching 패턴
2021/02/12 - [Study Note/Javascript] - javascript #디자인패턴 - Self-defining function 패턴
2021/02/13 - [Study Note/Javascript] - javascript #디자인패턴 - 메모이제이션 패턴 (memoization pattern)
2021/02/13 - [Study Note/Javascript] - javascript #디자인패턴 - Self-invoking constructor 패턴
2021/02/13 - [Study Note/Javascript] - javascript #디자인패턴 - 콜백 패턴(callback pattern)
'Study Note > Javascript' 카테고리의 다른 글
javascript #함수형 자바스크립트 프로그래밍 - 1~2장 기록 (0) | 2021.11.29 |
---|---|
javascript #DOM reflow 시 자원 소모 최소화 방법 (0) | 2021.02.14 |
javascript #디자인패턴 - 콜백 패턴(callback pattern) (0) | 2021.02.13 |
javascript #디자인패턴 - Self-invoking constructor 패턴 (0) | 2021.02.13 |
javascript #디자인패턴 - 메모이제이션 패턴 (memoization pattern) (0) | 2021.02.13 |
댓글