Advanced Closures & Currying
📖 Concept
Currying transforms a function that takes multiple arguments into a sequence of functions each taking a single argument: f(a, b, c) → f(a)(b)(c).
Partial Application fixes some arguments of a function, producing a function with fewer arguments.
Both leverage closures to "remember" previously supplied arguments.
🏠 Real-world analogy: Currying is like a burger assembly line. Station 1 adds the bun (first arg). Station 2 adds the patty (second arg). Station 3 adds toppings (third arg). Each station remembers what was added before.
💻 Code Example
1// Basic currying2function curry(fn) {3 return function curried(...args) {4 if (args.length >= fn.length) {5 return fn.apply(this, args);6 }7 return function(...args2) {8 return curried.apply(this, args.concat(args2));9 };10 };11}1213const add = (a, b, c) => a + b + c;14const curriedAdd = curry(add);15console.log(curriedAdd(1)(2)(3)); // 616console.log(curriedAdd(1, 2)(3)); // 617console.log(curriedAdd(1)(2, 3)); // 61819// Practical currying20const multiply = curry((a, b) => a * b);21const double = multiply(2);22const triple = multiply(3);23console.log([1,2,3].map(double)); // [2, 4, 6]2425// Partial application26function partial(fn, ...presetArgs) {27 return function(...laterArgs) {28 return fn(...presetArgs, ...laterArgs);29 };30}31const addTax = partial(multiply, 1.2);32console.log(addTax(100)); // 1203334// Advanced closure: function composition with currying35const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);36const processPrice = pipe(37 multiply(1.2), // Add 20% tax38 (x) => x.toFixed(2), // Format39 (x) => `$${x}` // Add currency40);41console.log(processPrice(100)); // "$120.00"
🏋️ Practice Exercise
Mini Exercise:
- Implement a generic
curryfunction that handles any number of arguments - Create a curried
logger(level)(module)(message)function - Build a curried API query builder:
query(table)(fields)(conditions) - Implement
partialandpartialRightfunctions
⚠️ Common Mistakes
Currying only works when function's
.lengthis accurate — rest params and defaults break thisOver-currying simple functions makes code harder to read — use it when it provides clear benefits
Confusing currying (one arg at a time) with partial application (fixing some args upfront)
Memory overhead — each curried call creates a new closure in memory
Not understanding that arrow functions with defaults have
.lengthof 0 for defaulted params
💼 Interview Questions
🎤 Mock Interview
Mock interview is powered by AI for Advanced Closures & Currying. Login to unlock this feature.