BRUCE_FEBRUCE_FE

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.

影片縮圖

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