Asher Cohen
Back to posts

Functional Programming Techniques in JavaScript

Practical functional programming patterns: compose, pipe, map, filter, reduce, and more

Introduction

Functional programming (FP) emphasizes immutability, pure functions, and function composition. JavaScript supports FP naturally with first-class functions and array methods. Master these techniques to write cleaner, more predictable code.

Core Concepts

Immutability

Never modify data; create new copies instead.

// ❌ Mutation
const user = { name: 'John', age: 30 };
user.age = 31;

// ✅ Immutability
const user = { name: 'John', age: 30 };
const updatedUser = { ...user, age: 31 };

Pure Functions

Always return the same output for the same input, with no side effects.

// ✅ Pure
const add = (a, b) => a + b;

// ❌ Impure
let counter = 0;
const increment = () => ++counter;

Function Composition

compose

Execute functions right-to-left.

const compose =
  (...functions) =>
  (data) =>
    functions.reduceRight((value, func) => func(value), data);

const addOne = (x) => x + 1;
const double = (x) => x * 2;
const square = (x) => x * x;

const transform = compose(square, double, addOne);
transform(3); // ((3 + 1) * 2)² = 64

pipe

Execute functions left-to-right (more intuitive).

const pipe =
  (...functions) =>
  (data) =>
    functions.reduce((value, func) => func(value), data);

const transform = pipe(addOne, double, square);
transform(3); // ((3 + 1) * 2)² = 64

Array Operations

map

Transform each element.

const users = [{ name: 'John' }, { name: 'Jane' }];
const names = users.map((user) => user.name);

filter

Select elements matching a condition.

const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter((n) => n % 2 === 0);

reduce

Accumulate values into a single result.

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, n) => acc + n, 0);

Handling Null and Undefined

Optional Chaining

const street = user?.address?.street;

Nullish Coalescing

const name = userName ?? 'Anonymous';

Practical Examples

Data Transformation Pipeline

const processOrders = pipe(
  (orders) => orders.filter((order) => order.status === 'completed'),
  (orders) =>
    orders.map((order) => ({
      id: order.id,
      total: order.items.reduce((sum, item) => sum + item.price, 0),
    })),
  (orders) => orders.sort((a, b) => b.total - a.total),
  (orders) => orders.slice(0, 10),
);

Best Practices

Keep Functions Small

Avoid Side Effects

Use Descriptive Names

Conclusion

Functional programming techniques lead to cleaner, more predictable code. Start with pure functions and array methods, then explore composition.

javascript #functional-programming #clean-code