前端面试题 - 113. 实现函数柯里化

175 阅读1分钟

实现

函数柯里化是一种转换函数的技术,通过将接受多个参数的函数转换为一系列接受单个参数的函数来实现。这些单参数的函数被称为柯里化函数。

const curry = (fn, ...args) => {
  if (args.length < fn.length) {
    // 未接受完参数,拼上参数
    return (..._args) => curry(fn, ...args, ..._args)
  } else {
    // 接受完所有参数,直接执行
    return fn(...args)
  }
}

const add = (a, b, c) => {
    return a + b + c
}

const curried = curry(add)

console.log(curried(1)(2)(3)) // 输出 6 
console.log(curried(1, 2)(3)) // 输出 6 
console.log(curried(1)(2, 3)) // 输出 6

应用

以下是一些常见的应用场景及其对应的代码示例:

  1. 参数复用和配置:
// 通用的请求函数
function request(method, baseUrl, headers, data) {
  // 发起请求的逻辑
}

// 柯里化的请求函数,固定了GET方法、基础URL和头部信息
const getApi = curry(request)('GET')('/api')({ 'Content-Type': 'application/json' });

// 使用特定的路径和数据进行请求
getApi('/users');
getApi('/posts');
  1. 函数组合和管道:
// 柯里化的加法和乘法函数
const add = (a) => (b) => a + b;
const multiply = (a) => (b) => a * b;

function pipe(...fns) {
  return function (initialValue) {
    return fns.reduce(function (result, fn) {
      return fn(result);
    }, initialValue);
  };
}

// 使用函数组合构建一个计算表达式的管道
const calculate = pipe(
  add(5),
  multiply(10)
);

console.log(calculate(2)); // 输出:70
  1. 延迟执行和部分应用:
// 柯里化的回调函数
const handleEvent = curry((eventType, callback, event) => {
  if (event.type === eventType) {
    callback(event);
  }
});

// 创建一个处理点击事件的回调函数
const handleClick = handleEvent('click', (event) => {
  console.log('Clicked:', event.target);
});

// 延迟执行回调函数
document.addEventListener('click', handleClick);
  1. 控制函数参数顺序:
// 柯里化的函数,参数顺序为 c, a, b
const myFunction = curry((c, a, b) => {
  // 函数逻辑
});

// 调用柯里化函数时,可以传入参数的任意顺序
myFunction(1)(2)(3);
myFunction(3)(1)(2);
myFunction(2)(3)(1);