일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- git
- npm
- Swift
- Xcode
- styled-components
- js
- JavaScript
- rn
- REACT
- Android
- shortcut
- ios
- vscode
- nextJS
- DevOps
- react-native
- React Native
- npm install
- Branch
- viewcontroller
- github
- HTML
- ReactNative
- styling
- Docker
- ES6
- commit
- GitLab
- currying
- xtring.log
- Today
- Total
xtring.dev
[JS] (번역)JavaScript Currying 이해하기⛓ 본문
🕺 원문
https://blog.logrocket.com/understanding-javascript-currying/
Currying은 람다 계산법 컨셉이지만 걱정할 필요없습니다.(간단합니다!)
Currying은 한번에 하나의 인자(argument)를 가지고 다음 인자를 함께 새로운 함수에 반환하는 함수입니다. 함수를 f(a, b, c)로 호출할 수 있는 함수에서 f(a)(b)(c)로 호출할 수 있는 함수로 변환하는 함수의 변환입니다.
이 아티클에서 JavaScript에서 Currying이 무엇이며, 왜, 어디에서 당신이 Currying을 사용해야하는지를 탐색해보겠습니다. 그리고 예제로 알아볼게요!
What is currying in JavaScript?
Currying은 단순히 여러 인자로 함수를 평가하고, 단일 인자로 함수 순서(sequence)를 분해하는 것을 의미합니다.
다시 말해서, 커링은 한 번에 모든 인자를 가지는 함수를 리턴하는 것과 달리 첫 번째 인자를 가지고 새 함수를 반환하고, 두번째 인수가 새로운 함수를 반환하고, 또 세번째 인자를 가진 다음 새 함수를 반환합니다. 이것은 모든 인자가 완료될때까지 실행됩니다.
Why should I use currying?
Currying이 이상적인 이유는 몇가지가 있습니다.
- Currying은 실행 전 필요한 것을 모두 얻었는지 확인하는 메소드입니다.
- 동일한 변수를 재 전달하는 것을 피하는데 도움이 됩니다.
- 다수의 하나의 책임을 다룰 수 있는 더 작은 함수들로 당신의 함수 쪼갭니다. 이것은 당신의 함수가 순수하고 오류 및 부작용이 적게 만들어 줍니다.
- Currying은 고차 함수(higher-order function)를 생성하기 위한 함수형 프로그래밍(functional programming)에 사용되곤 합니다.
How does currying work?
Currying은 다수의 인자를 받는 함수입니다. 이 함수는 모든 작은 함수가 하나의 인자를 받아들이는 일련의 함수로 변환될 것입니다.
// Noncurried version
const add = (a, b, c)=>{
return a+ b + c
}
console.log(add(2, 3, 5)) // 10
// Curried version
const addCurry =(a) => {
return (b)=>{
return (c)=>{
return a+b+c
}
}
}
console.log(addCurry(2)(3)(5)) // 10
JavaScript에서 Currying은 함수를 정의하는 측면에서 약깐 까다로울 수 있지만 구현할수록 분명해질 것입니다.
그래서, 더 많은 코드 예제로 나눠봅시다!
Example one: A simple, three-parameter function
첫번째로, 나는 세 인자들을 받는 간단한 함수를 생성해보겠습니다.
const add =(a, b, c)=>{
return a+b+c
}
console.log(add(2, 3, 5)) // 10
이 함수(add)는 10이라는 결과를 리턴합니다.
이 함수는 우리가 전달한 숫자의 모든 매개변수를 추가한다는 것입니다.
지금, 첫번째 예제는 단순히 다수의 매개변수를 받는 함수입니다.
기존 함수를 어떻게 curried version 함수로 변환할 수 있을까요?
Example two: Converting an existing function into a curried function
두번째 예제를 시도하고 어떻게 우리가 Curry function을 구현할지 봅시다.
이 예제에서, 이 함수는 하나의 인자를 받을 것입니다. 그리고 함수들을 순차적으로 반환합니다.
const addCurry =(a) => {
return (b)=>{
return (c)=>{
return a+b+c
}
}
}
이는 함수의 curry 수행 방법을 보여줍니다. 출력하면 10이 나옵니다!
console.log(addCurry(2)(3)(5)) // 10
첫번째 예제에서 세 개의 인수 a, b, c를 받아들이고 그 합 a + b + c, (2) + (3) + (5)를 더하고 출력을 10으로 반환
addCurry 함수를 만들었습니다.
이 두 번째 예제는 동일한 결과를 보여주는 함수를 구현했지만, 하나의 인자를 가지고 다른 인수 b를 가진 함수를 반환하는 Curry을 사용하여 다른 인자 c를 가지고 함수를 반환하고 해당 함수가 합을 반환하는 방법을 보여주었습니다. 예제 1과 동일한 출력: 10.
여기서 우리가 한 것은 중첩된(nested) 함수입니다. 각 함수는 다른 인자를 반환하는 하나의 인수를 취하고 모든 매개변수를 수신할 때까지 함수가 완료되지 않습니다.(순서를 보장한다.)
Example three: Creating a friend request curry function
이 예제는 유저가 그의 친구인 John에게 친구 요청을 보내는 간단한 Curry function을 생성할 것입니다.
function sendRequest(greet){
return function(name){
return function(message){
return `${greet} ${name}, ${message}`
}
}
}
sendRequest('Hello')('John')('Please can you add me to your Linkedin network?')
// "Hello John, Please can you add me to your Linkedin network?"
Basic vs. advanced currying techniques
Basic currying
const getPanCakeIngredients = (ingredient1) =>{
return (ingredient2) => {
return (ingredient3) => {
return ${ingredient1}, ${ingredient2}, ${ingredient3};
}
}
}
getPanCakeIngredients('Egg')('flour')('milk');
이 함수는 모든 매개변수를 받기 전까지 완성되지 않습니다. 이는 만약 펜케이크를 위한 ingredient들이 완전하지 않는다면, 이 함수는 좋은 결과를 반환하지 않습니다.
Advanced currying
여기에 진화된 currying 코드 예제가 있습니다.
const curry = (fn) =>{
return curried = (...args) => {
if (fn.length !== args.length) {
return curried.bind(null, ...args)
}
return fn(...args);
};
}
const totalNum = (x,y,z) => {
return x+y+z
}
const curriedTotal = curry(totalNum);
console.log(curriedTotal(10) (20) (30));
위 예제에서는 고정된 숫자 매개변수가 필요한 함수를 생성했습니다.
외부함수로 함수 curry를 받습니다. 이 함수는 rapper 함수입니다. 먼저, 함수 길이를 비교하고 spread operator(...args)로 인자를 받는 curried 함수와 또 다른 함수를 리턴합니다.
함수 길이는 여기에 전달하는 매개변수의 수가 어떻게 되던지 함수의 길이 property에 반영됨을 의미합니다.
그러나, 인자는 매번 증가할 것 입니다. 필요한 매개변수의 수가 같지 않으면 Curry를 반환합니다. bind를 호출하면 새 함수가 생성되고 ( ...args)를 전달합니다.
*참고: bind는 새로운 함수를 생성합니다.
Modern currying with ES6
ES6 arraw function을 사용하는 것으로 currying을 더 모던하고 적은 양의 코드로 구현할 수 있습니다.
const sendRequest = greet => name => message => `${greet} ${name}, ${message}`
sendRequest('Hello')('John')('Please can you add me to your Linkedin network?')
// "Hello John, Please can you add me to your Linkedin network?"
Currying Can be used to manipulate the DOM in JavaScript
const updateElemText = id => content => document.querySelector(`#${id}`).textContent= content;
const updateHeaderText = updateElemText('header');
updateHeaderText('Hello Samuel!');
// header 엘리먼트에 'Hello Samuel!'이 표현됨
Currying vs. partial application
이제 Currying이 작동하는 방식을 알았습니다. Currying과 partial application의 차이점은 무엇입니까? 이것은 프로그래머가 계속 묻는 질문 중 하나입니다.
나는 마침내 이 질문에 대한 답을 얻었습니다. 그러나 몇 가지 코드 예제를 사용하여 이 설명을 더 자세히 설명하기 전에 해당 정의에 익숙해지는 것이 가장 좋습니다.
- Currying: 여러 인자(argument)를 허용하는 함수입니다. 이 함수를 일련의 함수로 변환합니다. 여기서 모든 작은 함수는 모든 인수가 완료될 때까지 단일 인수를 받아들입니다.
- Partial application: 함수에 예상보다 적은 인수가 주어지면 함수가 부분적으로 적용되고 나머지 인수를 예상하는 새 함수를 반환합니다.(사이드 이펙트가 발생할 수 있다. 순수함수가 되지 않는다.)
정의를 아는 것만으로는 차이점을 이해하기에 충분하지 않습니다. 커링이 작동하는 것을 보았지만 다음은 partial application의 예입니다.
const addPartial = (x, y, z) => {
return x + y + z
}
const partialFunc= addPartial.bind(this, 2, 3);
partialFunc(5); //returns 10
Conclusion
- Currying은 Javascript에서 DOM을 조작하는 데 사용할 수 있습니다.
- 이벤트 리스너를 트리거하는 데 사용할 수 있습니다.
- 단일 인수만 수신하는 함수를 생성하려는 경우 Currying을 사용할 수 있습니다.
'Front-End > JavaScript' 카테고리의 다른 글
[JS] ?? - null 병합 연산자 (0) | 2020.11.10 |
---|---|
[JS] 자바스크립트 기본 - 비교 연산자 (0) | 2020.11.09 |
[JS] if문, 삼항연산자 어떤 것이 더 빠를까? (0) | 2020.04.20 |
[JS] ES6의 Arrow Function를 알아보자! (0) | 2020.01.04 |
[JS] 함수선언(Function Declarations) (0) | 2020.01.04 |