On this page
Functional Programming
Functional programming (FP) treats computation as the evaluation of functions and emphasizes avoiding mutable state and side effects.
Core Principles
1. Pure Functions
Same input always produces same output; no side effects:
// Pure
function add(a, b) {
return a + b;
}
// Impure — depends on external state
let counter = 0;
function increment() {
return ++counter;
}
// Impure — modifies input
function appendItem(arr, item) {
arr.push(item);
return arr;
}
2. Immutability
Create new values instead of mutating existing ones:
// Mutable
let user = { name: 'Alice', age: 25 };
user.age = 26;
// Immutable update
let updatedUser = { ...user, age: 26 };
let newTags = [...user.tags, 'vip']; // if tags existed
3. First-Class Functions
Functions are values — assign, pass, return them:
const operations = {
add: (a, b) => a + b,
multiply: (a, b) => a * b
};
map, filter, reduce
The foundation of functional array processing:
let numbers = [1, 2, 3, 4, 5];
let doubled = numbers.map(n => n * 2);
let evens = numbers.filter(n => n % 2 === 0);
let sum = numbers.reduce((acc, n) => acc + n, 0);
// Chain
let result = numbers
.filter(n => n % 2 === 0)
.map(n => n * 2)
.reduce((acc, n) => acc + n, 0);
console.log(result); // 12 (2*2 + 4*2)
Declarative vs Imperative
// Imperative
let total = 0;
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] % 2 === 0) {
total += numbers[i] * 2;
}
}
// Declarative
let total2 = numbers
.filter(n => n % 2 === 0)
.map(n => n * 2)
.reduce((a, b) => a + b, 0);
Avoiding Side Effects
// Side effect: modifies external state
let log = [];
function process(data) {
log.push(data); // side effect
return data.toUpperCase();
}
// No side effect: return new data, log separately
function processPure(data) {
return data.toUpperCase();
}
Recursion
Functional style often uses recursion instead of loops:
function sumArray(arr) {
if (arr.length === 0) return 0;
return arr[0] + sumArray(arr.slice(1));
}
function factorial(n) {
return n <= 1 ? 1 : n * factorial(n - 1);
}
Maybe / Optional Pattern (Manual)
Handle null/undefined without exceptions:
const Maybe = {
of(value) {
return {
isNothing: value == null,
value,
map(fn) {
return this.isNothing ? this : Maybe.of(fn(this.value));
},
getOr(defaultVal) {
return this.isNothing ? defaultVal : this.value;
}
};
}
};
Maybe.of(null).map(x => x * 2).getOr(0); // 0
Maybe.of(5).map(x => x * 2).getOr(0); // 10
When to Use FP
- Data transformation pipelines
- React state updates (immutability)
- Testing (pure functions are easy to test)
- Concurrent code (no shared mutable state)
Functional techniques complement OOP — JavaScript supports both styles effectively.