새소식

반응형
Javascript/Clean Code Series(클린코드)

[JavaScript] 프론트엔드 개발자를 위한 함수형 프로그래밍(functional programming)

  • -
반응형

a programer generated by AI

JavaScript 개발자를 위한 함수형 프로그래밍

JavaScript는 다양한 스타일로 코드를 작성할 수 있는 유연한 언어입니다. 명령형(imperative), 객체 지향(object-oriented), 그리고 함수형(functional) 프로그래밍 스타일을 모두 지원하며, 각각의 스타일은 문제를 해결하는 방식이 다릅니다.

 

이 중 함수형 프로그래밍은 진입 장벽이 높다고 느껴질 수 있지만, 사실 JavaScript를 사용하면서 이미 함수형 스타일을 활용하고 있을 가능성이 큽니다. 다만, 함수형 프로그래밍은 낯선 용어와 개념 때문에 어렵게 느껴질 수 있습니다. 이 글에서는 함수형 프로그래밍을 실용적인 방식으로 소개하여, 지금 당장 코드에 적용할 수 있도록 도와드리겠습니다.


함수형 프로그래밍이란?

객체 지향 프로그래밍(OOP)이 객체를 중심으로 코드를 구조화하는 것처럼, 함수형 프로그래밍은 함수를 중심으로 구조화합니다. 이를 위해 몇 가지 중요한 개념을 따릅니다.

1. 함수는 "일급 시민(First-Class Citizen)"이다.

JavaScript에서 함수는 변수에 할당할 수 있고, 다른 함수의 인자로 전달되거나, 함수에서 반환될 수도 있습니다.

const messageCreator = () => '함수가 실행되었습니다!';

function executeFunction(fn) {
  return () => fn();
}

const executeMsg = executeFunction(messageCreator);
console.log(executeMsg()); // '함수가 실행되었습니다!'

함수를 값처럼 다룰 수 있기 때문에, 코드의 유연성이 높아집니다.


2. 순수 함수(Pure Function)와 함수 조합(Composition)

순수 함수란 동일한 입력값에 대해 항상 같은 결과를 반환하며, 부수 효과(side effect)가 없는 함수를 의미합니다. 즉, 함수 외부의 상태를 변경하지 않습니다.

순수하지 않은 함수 (부수 효과 발생)

let currentUser = null;

function fetchUserById(id) {
  currentUser = getUserFromDB({ id }); // 외부 변수 변경
}
fetchUserById('A123');

순수한 함수 (부수 효과 없음)

function fetchUserById(id) {
  return getUserFromDB({ id });
}
const userData = fetchUserById('A123');

순수 함수는 부작용이 없기 때문에 테스트하기 쉽고, 유지보수가 용이합니다.


3. 불변성(Immutable)과 데이터 변환(Data Transformation)

함수형 프로그래밍에서는 데이터를 변경하는 것이 아니라, 기존 데이터를 기반으로 새로운 데이터를 생성하는 방식을 사용합니다.

배열을 변경하는 방식

let numbers = [];
numbers.push(5);

새로운 배열을 생성하는 방식

let numbers = [];
const updatedNumbers = numbers.concat(5);
// 또는
const updatedNumbers = [...numbers, 5];

객체를 변경하는 방식

let userProfile = {};
userProfile.age = 30;

새로운 객체를 생성하는 방식

const updatedProfile = Object.assign({}, userProfile, { age: 30 });
// 또는
const updatedProfile = { ...userProfile, age: 30 };

이러한 방식은 예기치 않은 변경을 방지하고, 코드의 예측 가능성을 높여줍니다.

반응형

함수형 프로그래밍의 이점

함수형 프로그래밍은 가독성이 뛰어나고, 유지보수가 쉬운 코드를 작성하는 데 도움이 됩니다. 명령형 방식과 비교하여 함수형 스타일이 어떻게 더 명확하고 선언적인 코드를 만드는지 예제를 통해 살펴보겠습니다.

 

👎 명령형(Imperative) 방식

아래는 숫자 배열을 받아 짝수만 필터링한 후, 각 숫자에 2를 곱한 뒤, 합계를 구하는 명령형 방식의 코드입니다.

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let sum = 0;

for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] % 2 === 0) {
    sum += numbers[i] * 2;
  }
}

console.log(sum); // 60

이 방식은 코드를 읽을 때 각 단계를 명확히 파악하기 어렵고, 로직이 분리되지 않아 유지보수가 어렵습니다.

 

👍 함수형(Functional) 방식

아래는 같은 로직을 함수형 스타일로 변환한 코드입니다.

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const result = numbers
  .filter(num => num % 2 === 0) // 짝수 필터링
  .map(num => num * 2) // 각 숫자에 2를 곱함
  .reduce((acc, num) => acc + num, 0); // 합계를 구함

console.log(result); // 60

함수형 코드의 장점:
더 선언적 → "무엇을" 할 것인지 명확하게 표현됨
단계가 명확하게 분리됨 → filter, map, reduce 각각의 역할이 뚜렷함
재사용 가능성이 높음 → 각 함수가 독립적이라 필요에 따라 쉽게 변경 가능

이처럼 함수형 스타일을 적용하면 코드의 가독성과 유지보수성이 크게 향상됩니다. 


실용적인 함수형 패턴

1. 데이터 불변성 유지

객체와 배열을 변경하는 것을 피하고, 새 데이터를 생성하는 방식을 사용하면 예기치 않은 부작용을 방지할 수 있습니다. 라이브러리로 immutable.js나 immer.js를 사용할 수도 있지만, Object.freeze() 또는 getter를 활용하는 것도 좋은 방법입니다.


2. 단일 책임 원칙을 적용한 함수 분리

각 함수는 단일 책임(Single Responsibility)을 가지도록 설계해야 합니다. 함수가 너무 많은 일을 하고 있다면, 여러 개의 작은 함수로 분리하는 것이 좋습니다.


3. 고차 함수(Higher-Order Functions) 활용

고차 함수란 함수를 인자로 받거나, 함수를 반환하는 함수를 의미합니다. JavaScript의 map, filter, reduce 같은 배열 메서드가 대표적인 예입니다.

const numbers = [1, 2, 3, 4, 5];

const squaredNumbers = numbers.map(num => num * num);
console.log(squaredNumbers); // [1, 4, 9, 16, 25]

4. 커링(Currying)과 부분 적용(Partial Application)

커링은 여러 개의 인자를 받는 함수를 하나의 인자만 받는 여러 개의 함수로 변환하는 기법입니다.

const multiply = x => y => x * y;
console.log(multiply(2)(3)); // 6

부분 적용은 특정 값을 미리 적용한 함수를 만드는 기법입니다.

const multiplyBy5 = multiply(5);
console.log(multiplyBy5(4)); // 20

이러한 패턴을 활용하면, 코드의 재사용성과 유연성이 높아집니다.


결론

함수형 프로그래밍은 처음에는 생소할 수 있지만, 점진적으로 적용하면 코드가 더 깔끔하고 유지보수가 쉬워집니다.

지금 당장 실천할 수 있는 방법

객체와 배열을 직접 변경하지 말고 새로운 값을 생성하기
순수 함수를 사용하여 예측 가능성을 높이기
단일 책임 원칙을 적용하여 함수를 작게 나누기
고차 함수 및 커링을 활용하여 코드의 재사용성을 높이기

 

이러한 기법을 적용하면 코드가 더 읽기 쉽고 유지보수가 편리해집니다. 

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.