EN/CH Mode
BRUCE_FE JS Interview Notes - Implement Curry Function
Learn how to implement JavaScript Curry functions, master partial application and parameter collection techniques in functional programming, and enhance frontend interview competitiveness.
EN/CH Mode
Lazy to read articles? Then watch videos!
What is Currying?
Currying is a technique that transforms a function that accepts multiple parameters into a series of functions that each use one parameter. This is a core concept in functional programming, originating from the work of mathematician Haskell Curry.
Simply put, currying transforms a function like f(a, b, c)
into the form f(a)(b)(c)
.
Benefits of Currying
- 1. Parameter reuse: Fix partial parameters to create more specialized functions
- 2. Lazy execution: Don't execute until enough parameters are collected, which can improve performance
- 3. Improve readability: Make code more modular and composable
- 4. Align with functional programming principles: Single responsibility principle and separation of concerns
Basic Implementation: Curry Function
The most basic curry function takes a multi-parameter function and returns a series of single-parameter functions:
// Basic curry function (fixed parameter count)
function curry(fn) {
// Get the number of parameters the original function needs
const arity = fn.length;
return function curried(...args) {
// If enough parameters are provided, call the original function directly
if (args.length >= arity) {
return fn.apply(this, args);
}
// Otherwise return a new function to continue collecting parameters
return function(...moreArgs) {
// Merge existing parameters with new parameters, recursive call
return curried.apply(this, [...args, ...moreArgs]);
};
};
}
Usage Example
// Define a regular addition function
function add(x, y, z) {
return x + y + z;
}
// Use currying
const curriedAdd = curry(add);
// Multiple calling methods (all results are 6)
console.log(curriedAdd(1, 2, 3)); // 6 - Provide all parameters at once
console.log(curriedAdd(1)(2)(3)); // 6 - Provide each parameter separately
console.log(curriedAdd(1, 2)(3)); // 6 - Mixed parameter provision
console.log(curriedAdd(1)(2, 3)); // 6 - Mixed parameter provision
// Can also create partial functions
const add1 = curriedAdd(1); // Fix first parameter as 1
console.log(add1(2, 3)); // 6
const add1and2 = curriedAdd(1)(2); // Fix first two parameters as 1 and 2
console.log(add1and2(3)); // 6
Practical Application Scenarios
Currying has many uses in practical development:
1. Event Handling Functions
// Event handling and logging
function handleEvent(eventType, element, event) {
console.log('event triggered on');
// Handle event...
}
// After currying
const curriedHandleEvent = curry(handleEvent);
// Create specific type event handling functions
const handleClick = curriedHandleEvent('click');
const handleKeypress = curriedHandleEvent('keypress');
// Create specific element event handling functions
const handleButtonClick = handleClick('button');
const handleInputKeypress = handleKeypress('input');
// Usage
button.addEventListener('click', handleButtonClick);
input.addEventListener('keypress', handleInputKeypress);
2. Function Composition and Pipeline
// Data processing pipeline
const multiply = curry((x, y) => x * y);
const add = curry((x, y) => x + y);
// Create specific functions
const double = multiply(2);
const triple = multiply(3);
const addTen = add(10);
// Compose functions
const pipeline = [double, addTen, triple];
const processData = (x) => pipeline.reduce((acc, fn) => fn(acc), x);
console.log(processData(5)); // ((5 * 2) + 10) * 3 = 60