This chapter follows Higher-order functions and callbacks.
These patterns show up in libraries and interview questions; in application code, reach for them when they simplify APIs or performance—not to avoid readable loops.
Immediately invoked function expressions (IIFE)
An IIFE runs a function once at load time, creating a private scope for var and early modules.
const module = (function () { let secret = 0; return { inc() { return ++secret; }, };})();Before ES modules, IIFEs avoided global pollution and loop-capture bugs with var. Today, prefer import/export; IIFEs remain useful for legacy bundles and tiny script snippets.
Currying
Currying turns a function of several arguments into a chain of functions each taking one argument (or a fixed smaller chunk). It helps partial application and uniform unary APIs.
const add = (a) => (b) => a + b;add(2)(3); // 5
function curry(fn) { return function curried(...args) { if (args.length >= fn.length) { return fn.apply(this, args); } return (...next) => curried(...args, ...next); };}Manual currying is verbose; lodash curry or hand-written wrappers are common when arity is stable.
Compose and pipe
Compose applies functions right-to-left; pipe goes left-to-right—same as mathematical composition versus reading order.
const compose = (...fns) => (x) => fns.reduceRight((v, f) => f(v), x);
const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);
const trimAndLower = pipe( (s) => s.trim(), (s) => s.toLowerCase(),);Use compose/pipe for pure data transforms; avoid deep stacks when debugging stack traces matters.
Memoize
Memoization caches results keyed by arguments so repeated calls with the same inputs skip work.
function memoize(fn) { const cache = new Map(); return (...args) => { const key = JSON.stringify(args); if (cache.has(key)) return cache.get(key); const result = fn(...args); cache.set(key, result); return result; };}Production memoizers use stronger keys (e.g. first argument identity), LRU eviction, and cache busting for unbounded argument spaces. React’s useMemo applies the same idea to render-derived values.
That completes the Functions and Scope series. For object models and this in prototypes, see Objects in JavaScript.