IT & 웹개발

함수형 프로그래밍과 JavaScript – 개념 및 예제

kkwako 2025. 4. 2. 18:38

1. 개요

함수형 프로그래밍(Functional Programming, FP)은 **순수 함수(Pure Function)**와 **불변성(Immutability)**을 기반으로 하는 프로그래밍 패러다임이다. JavaScript는 객체 지향과 함수형 프로그래밍을 모두 지원하는 멀티 패러다임 언어지만, 최근 React, Redux와 같은 라이브러리의 등장으로 함수형 프로그래밍의 중요성이 더욱 커지고 있다.

본 글에서는 함수형 프로그래밍의 핵심 개념과 원칙을 이해하고, JavaScript에서 이를 어떻게 활용할 수 있는지 살펴본다.


2. 함수형 프로그래밍의 주요 개념

(1) 순수 함수(Pure Function)

순수 함수는 동일한 입력값에 대해 항상 동일한 결과를 반환하며, 외부 상태를 변경하지 않는 함수를 의미한다.

javascript
복사편집
// 순수 함수 예제 function add(a, b) { return a + b; // 외부 상태 변경 없음 } console.log(add(2, 3)); // 5 console.log(add(2, 3)); // 항상 같은 결과 (5)

반대로, 외부 상태를 변경하는 함수는 순수 함수가 아니다.

javascript
복사편집
let total = 0; function impureAdd(a) { total += a; // 외부 변수 변경 (부작용 발생) return total; } console.log(impureAdd(2)); // 2 console.log(impureAdd(3)); // 5 (같은 입력인데 다른 결과)

✅ 순수 함수의 장점

  • 코드 예측이 쉬움 (입력 → 출력이 고정됨)
  • 테스트 및 디버깅이 쉬움
  • 멀티스레드 환경에서도 안전하게 실행 가능

(2) 불변성(Immutability)

함수형 프로그래밍에서는 데이터의 변경을 허용하지 않음(Immutable). 변경이 필요할 경우, 새로운 값을 반환해야 한다.

javascript
복사편집
const person = { name: "Alice", age: 25 }; // 객체 변경을 피하고 새로운 객체를 생성 const updatedPerson = { ...person, age: 26 }; console.log(person); // { name: "Alice", age: 25 } (원본 유지) console.log(updatedPerson); // { name: "Alice", age: 26 } (새 객체)

배열에서도 불변성을 유지하기 위해 map, filter, reduce 등을 사용한다.

javascript
복사편집
const numbers = [1, 2, 3, 4, 5]; // 기존 배열 변경 없이 새로운 배열 반환 const squaredNumbers = numbers.map((n) => n * n); console.log(numbers); // [1, 2, 3, 4, 5] (원본 유지) console.log(squaredNumbers); // [1, 4, 9, 16, 25]

✅ 불변성의 장점

  • 버그 방지: 원본 데이터를 변경하지 않으므로, 예상치 못한 오류를 줄일 수 있음
  • 리액티브 프로그래밍: Redux와 같은 상태 관리 라이브러리에서 변경 추적이 용이

(3) 일급 함수(First-Class Function) & 고차 함수(Higher-Order Function)

JavaScript에서는 함수가 일급 객체(First-Class Citizen)이므로, 변수를 할당하거나 함수의 인자로 전달 가능하다.

javascript
복사편집
// 함수가 변수에 저장될 수 있음 const sayHello = function () { return "Hello!"; }; console.log(sayHello()); // "Hello!"

또한, **고차 함수(Higher-Order Function)**는 함수를 인자로 받거나 함수를 반환하는 함수다.

javascript
복사편집
// 함수를 인자로 받는 고차 함수 function applyOperation(x, y, operation) { return operation(x, y); } function multiply(a, b) { return a * b; } console.log(applyOperation(3, 4, multiply)); // 12

고차 함수는 map, filter, reduce 같은 내장 함수에서도 활용된다.

javascript
복사편집
const numbers = [1, 2, 3, 4, 5]; const evenNumbers = numbers.filter((n) => n % 2 === 0); console.log(evenNumbers); // [2, 4]

✅ 고차 함수의 장점

  • 코드 재사용성 증가
  • 코드가 더 간결하고 가독성이 높아짐
  • 함수 조합(composition)이 가능

(4) 함수 합성(Composition)과 커링(Currying)

1) 함수 합성(Composition)

여러 개의 함수를 조합하여 새로운 함수를 생성하는 기법이다.

javascript
복사편집
const toUpperCase = (str) => str.toUpperCase(); const appendExclamation = (str) => str + "!"; // 두 함수를 조합하여 새로운 함수 생성 const excitedGreeting = (name) => appendExclamation(toUpperCase(name)); console.log(excitedGreeting("hello")); // "HELLO!"

2) 커링(Currying)

커링은 하나의 함수에서 여러 개의 인자를 받는 대신, 부분적으로 인자를 적용하는 기법이다.

javascript
복사편집
const add = (a) => (b) => a + b; const addFive = add(5); // 첫 번째 인자 적용 console.log(addFive(3)); // 8 (5 + 3) console.log(addFive(10)); // 15 (5 + 10)

✅ 커링과 함수 합성의 장점

  • 코드 재사용성 증가
  • 부분 적용(Partial Application)이 가능하여 유연한 코드 작성 가능

3. 함수형 프로그래밍을 활용한 예제

(1) 배열 데이터 가공

javascript
복사편집
const products = [ { name: "Laptop", price: 1000 }, { name: "Phone", price: 500 }, { name: "Tablet", price: 300 }, ]; // 500달러 이상인 제품만 필터링하고, 가격을 10% 할인 적용 const discountedProducts = products .filter((product) => product.price >= 500) .map((product) => ({ ...product, price: product.price * 0.9 })); console.log(discountedProducts); // [{ name: "Laptop", price: 900 }, { name: "Phone", price: 450 }]

(2) 순수 함수와 불변성 적용

javascript
복사편집
const user = { name: "Alice", age: 25 }; // 나이 업데이트 함수 (불변성 유지) const updateAge = (user, newAge) => ({ ...user, age: newAge }); const updatedUser = updateAge(user, 30); console.log(updatedUser); // { name: "Alice", age: 30 } console.log(user); // { name: "Alice", age: 25 } (원본 유지)

✅ 함수형 프로그래밍을 활용하면 데이터 변형을 최소화하고, 예측 가능한 코드 작성이 가능하다.


4. 결론

JavaScript에서 함수형 프로그래밍을 적용하면 코드를 더 읽기 쉽고, 유지보수하기 좋은 방식으로 작성할 수 있다.

핵심 요약

  • 순수 함수를 사용하면 부작용(Side Effect)을 최소화할 수 있다.
  • 불변성(Immutable)을 유지하면 상태 변화로 인한 오류를 줄일 수 있다.
  • 고차 함수와 함수 합성을 활용하면 코드의 재사용성이 증가한다.
  • **커링(Currying)**을 사용하면 함수를 부분적으로 적용할 수 있어 유연성이 증가한다.

함수형 프로그래밍을 이해하고 적용하면 보다 효율적이고 유지보수하기 쉬운 JavaScript 코드 작성이 가능하다.

 

함수형 프로그래밍과 JavaScript – 개념 및 예제