프론트엔드/JS
[JavaScript] go, pipe로 읽기 좋은 코드 만들기
턴태
2023. 4. 27. 23:50
기존 함수의 문제
https://dev-scratch.tistory.com/150
앞선 게시물에서 여러 개의 함수를 중첩하여 사용하다보니까 코드는 간결하지만 가독성이 그리 좋지 않았다. 그렇기에 이를 보완할 필요가 있어 보인다.
const filter = (f, iter) => {
const res = [];
for (const a of iter) {
if (f(a)) res.push(a);
}
return res;
};
const reduce = (f, acc, iter) => {
if (!iter) {
iter = acc[Symbol.iterator]();
acc = iter.next().value;
}
for (const a of iter) {
acc = f(acc, a);
}
return acc;
};
const products = [
{ name: '반팔티', price: 15000 },
{ name: '긴팔티', price: 20000 },
{ name: '핸드폰케이스', price: 15000 },
{ name: '후드티', price: 30000 },
{ name: '바지', price: 25000 },
];
const add = (a, b) => a + b;
reduce(add, map(p => p.price, filter(p => p.price < 20000, products))));
위 코드는 읽기 편한 코드가 아니기 때문에 가독성을 높일 필요가 있어 보인다.
Go 함수 만들기
const go = () => {};
go(
0,
a => a + 1,
a => a + 10,
a => a + 100,
console.log(a));
);
// 111
위처럼 뼈대를 만들었을 때, 원하는 과정은 a의 값을 점점 업데이트하면서 111이라는 값을 얻고자 한다.
const go = (...args) => {};
일단 위처럼 수정하면, 함수 매개변수들을 받아 사용할 수 있다.
여기서 reduce를 안에 넣어 사용해볼 수 있다.
const go = (...args) => reduce((a, f) => f(a), args);
go(
0,
a => a + 1,
a => a + 10,
a => a + 100,
console.log(a)
);
위처럼 작성하면 reduce함수에 내가 원하는 함수들을 인자로 넣어 값을 조금 더 가독성 있게 풀어낼 수 있다.
pipe 함수
go 함수는 함수들과 인자를 전달해 즉시 값을 계산해 전달한다. pipe 함수는 함수를 리턴하는 함수로, 함수들을 합성한다.
const pipe = () => () => {};
const f = pipe(
a => a + 1,
a => a + 10,
a => a + 100);
이렇게 작성했을 때, f(0)을 호출해 앞선 결과와 똑같이 111을 리턴하는 함수를 만들 차례이다.
pipe 함수는 내부적으로 go를 사용하는 함수이다.
const pipe = (...fs) => (a) => go(a, ...fs);
이를 다음과 같이 불러와 사용한다.
const f = pipe(
a => a + 1,
a => a + 10,
a => a + 100,
);
f(0);
즉, f에게 pipe 함수를 실행하면,
f = (a) => go(a,
a => a + 1,
a => a + 10,
a => a + 100,
);
와 같은 꼴이 되는 것이다.
여기서 기능을 추가해보자.
첫 번째 값이 여러 개의 인자를 받고자 할 때 아래와 같이 수정할 수 있다.
const pipe = (f, ...fs) => (...as) => go(f(...as), ...fs);
const f = pipe(
(a, b) => a + b,
a => a + 10,
a => a + 100
);
f(0, 1);
즉 이는 아래와 같은 의미이다.
f = (...as) => go((a, b) => a + b, ...fs);