blog.dopana

Back

Functional programming (FP) là paradigm coi tính toán như evaluation của function, tránh state và mutable data. Không chỉ dành cho Haskell — áp dụng FP trong JS/TS giúp code dễ đoán, dễ test.

Pure Function — Hàm Thuần Khiết#

// ❌ Impure — phụ thuộc external state
let taxRate = 0.1;
function calculatePrice(price: number) {
  return price + price * taxRate; // taxRate có thể thay đổi
}

// ✅ Pure — cùng input → cùng output, không side effect
function calculatePrice(price: number, taxRate: number) {
  return price + price * taxRate;
}
typescript

Lợi ích: Dễ test (không cần mock), dễ cache (memoization), dễ debug.

Immutability — Không Thay Đổi#

Immer — thư viện giúp immutable dễ dàng:

import { produce } from 'immer';

const state = { users: [{ id: 1, name: 'Alice' }] };

const nextState = produce(state, (draft) => {
  draft.users[0].name = 'Bob';
});
// state không thay đổi, nextState là object mới
typescript

Higher-Order Function — Hàm Bậc Cao#

Function nhận function làm tham số hoặc trả về function:

// HOF — trả về function
function createLogger(prefix: string) {
  return (message: string) => {
    console.log(`[${prefix}] ${message}`);
  };
}

const infoLogger = createLogger('INFO');
const errorLogger = createLogger('ERROR');

infoLogger('Server started');  // [INFO] Server started
errorLogger('Connection failed');  // [ERROR] Connection failed
typescript

Map, Filter, Reduce — Ba Trụ Cột#

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

// Map — biến đổi từng phần tử
const doubled = numbers.map(n => n * 2);
// [2, 4, 6, 8, 10]

// Filter — lọc
const even = numbers.filter(n => n % 2 === 0);
// [2, 4]

// Reduce — gom về một giá trị
const sum = numbers.reduce((acc, n) => acc + n, 0);
// 15
typescript

Ví dụ Thực Tế#

Function Composition — Kết Hợp Function#

Curry — Function Có Sẵn Tham Số#

// Curry — function nhận từng tham số một
const multiply = (a: number) => (b: number) => a * b;

const double = multiply(2);
const triple = multiply(3);

console.log(double(5));  // 10
console.log(triple(5));  // 15
typescript

Maybe — Xử Lý Null An Toàn#

Lợi Ích Của FP#

Vấn đềOOPFP
StateObject mutationImmutability
Side effectsMethod gọi methodPure functions
Error handlingtry/catchEither, Maybe
Loopsfor, whilemap, filter, reduce
DependenciesDI, mockPure function, no mock needed

FP Trong React#

React khuyến khích FP:

// Component là pure function (lý tưởng)
function UserCard({ user }: { user: User }) {
  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div>
  );
}

// useReducer + dispatch → reducer là pure function
// Immer + useState → immutable state
tsx

Kết Luận#

Bạn không cần chuyển hoàn toàn sang FP — chỉ cần áp dụng một số nguyên tắc:

  • Pure functions cho logic business — dễ test
  • Immutability — tránh bug khó lường
  • map/filter/reduce — thay for loop
  • Function composition — code nhỏ, kết hợp linh hoạt

FP làm code dễ hiểu, dễ kiểm tra, dễ bảo trì. Không phải “tất cả hoặc không” — hãy áp dụng dần.

Tài liệu tham khảo#