함수형 프로그래밍
JavaScript 함수형 프로그래밍
함수를 일급 시민으로 취급하고, 부수 효과를 피하며, 불변 데이터를 다루는 프로그래밍 패러다임.
핵심 개념
일급 시민 (First-class Citizen)
함수를 다음처럼 다룰 수 있다:
- 변수에 할당
- 함수의 인자로 전달
- 함수의 반환값으로 사용
순수 함수 (Pure Function)
- 동일한 입력 → 항상 동일한 출력
- 외부 상태를 변경하지 않음 (Side Effect 없음)
- 참조 투명성 보장
불변성 (Immutability)
- 값이 한 번 할당되면 변경되지 않음
- 람다 계산법의 근간
- 예측 가능한 코드 작성 가능
클로저 (Closure)
- 람다 계산식의 구현체
- 이름 없는 함수로 리터럴하게 작성 가능
- 선언된 범위(스코프)의 변수를 캡처해서 저장
// JS 클로저 — 캡처한 변수를 참조
const fizz = (index) => (index % 3 === 0) ? "fizz" : "";
const buzz = (index) => (index % 5 === 0) ? "buzz" : "";
고차함수 (Higher-Order Functions)
map
각 요소를 변환하여 새로운 배열 생성. 원본 불변.
var arr = ['foo', 'hello', 'diamond', 'A'];
var arr2 = arr.map((v) => v.length);
// [3, 5, 7, 1]
filter
조건을 만족하는 요소들만 모아 새로운 배열 생성.
var arr = [4, 15, 377, 395, 400, 1024, 3000];
var arr2 = arr.filter((v) => (v % 5 === 0));
// [15, 395, 400, 3000]
reduce
배열 요소를 순회하며 하나의 결과값 생성.
let arr = [9, 2, 8, 5, 7];
let sum = arr.reduce((pre, val) => pre + val);
// 31
// map을 reduce로 구현
var arr2 = arr.reduce((pre, value) => {
pre.push(value.length);
return pre;
}, []);
reduce는map과filter모두 구현 가능 — 가장 범용적인 고차함수.
FizzBuzz로 보는 함수형 진화
// 1. 절차적
function fizzbuzz1() {
for (let index = 1; index <= 100; index++) {
const isFizz = index % 3 === 0;
const isBuzz = index % 5 === 0;
// switch ...
}
}
// 2. 클로저 활용 — 각 판단 로직을 함수로 분리
function fizzclosure() {
const fizz = (index) => (index % 3 === 0) ? "fizz" : "";
const buzz = (index) => (index % 5 === 0) ? "buzz" : "";
Array(100).fill().map((x, i) => i + 1).forEach(index => {
let result = fizz(index) + buzz(index);
console.log(result.length == 0 ? `${index}` : result);
});
}
// 3. 선언적 — 모든 로직을 클로저 변수로
function fizzDeclarative() {
const fizz = (index) => (index % 3 === 0) ? "fizz" : "";
const buzz = (index) => (index % 5 === 0) ? "buzz" : "";
const fizzbuzz = (index) => {
let result = fizz(index) + buzz(index);
return result.length == 0 ? `${index}` : result;
};
Array(100).fill().map((x, i) => i + 1).map(fizzbuzz).forEach(console.log);
}
불변성 라이브러리
- Immer: Proxy 패턴으로 원본 보호. 수정 시도 시 복사본 생성 후 변경 적용
- Immutable.js: 불변 자료구조 전용 라이브러리
참고
- 학습 출처: 네이버 부스트캠프 챌린지 Day8