前端面试题 - 114. 实现compose函数

561 阅读2分钟

实现

compose函数通常用于函数式编程中,它接受多个函数作为参数,并返回一个新的函数,该函数将按照参数列表中的顺序依次调用这些函数。

for循环实现

function compose(...functions) {
  return function(init) {
    let result = init;
    for (let i = functions.length - 1; i >= 0; i--) {
      result = functions[i](result);
    }
    return result;
  };
}

reduce实现

function compose(...functions) {
  return function(init) {
    return functions.reduceRight(function(result, fn) {
      return fn(result);
    }, init);
  };
}

这个compose函数接受任意数量的函数作为参数,并返回一个新的函数。新函数将按照参数列表中的顺序依次调用这些函数。

下面是一个使用示例:

function addOne(x) {
  return x + 1;
}

function multiplyByTwo(x) {
  return x * 2;
}

function subtractThree(x) {
  return x - 3;
}

const composedFunction = compose(subtractThree, multiplyByTwo, addOne);

const result = composedFunction(5);
console.log(result); // 输出:9。解释:(5 + 1) * 2 - 3

在这个例子中,我们定义了三个函数addOne、multiplyByTwo和subtractThree,分别对应加1、乘以2和减去3的操作。然后,使用compose函数将它们组合成一个新的函数composedFunction。最后,我们将输入值5传递给composedFunction,并打印输出结果9。

应用

下面是一些使用compose函数的代码示例:

  1. 函数链式调用:
function toUpperCase(str) {
  return str.toUpperCase();
}

function removeSpaces(str) {
  return str.replace(/\s+/g, '');
}

function reverseString(str) {
  return str.split('').reverse().join('');
}

const processString = compose(toUpperCase, removeSpaces, reverseString);

const result = processString(' Hello World ');
console.log(result); // 输出:DLROWOLLEH

在这个示例中,我们定义了三个函数:toUpperCase用于将字符串转换为大写,removeSpaces用于移除字符串中的空格,reverseString用于反转字符串。然后,我们使用compose函数将这三个函数按照顺序组合成一个新的函数processString。最后,我们将输入字符串' Hello World '传递给processString函数,输出结果为'DLROWOLLEH'。

  1. 中间件管道:
// 中间件1
function loggerMiddleware(next) {
  return function(arg) {
    console.log('Start logging...');
    const result = next(arg);
    console.log('End logging.');
    return result;
  };
}

// 中间件2
function authorizationMiddleware(next) {
  return function(arg) {
    console.log('Authorizing...');
    // 进行授权逻辑
    const result = next(arg);
    console.log('Authorization completed.');
    return result;
  };
}

// 中间件3
function dataProcessingMiddleware(next) {
  return function(arg) {
    console.log('Processing data...');
    // 进行数据处理逻辑
    const result = next(arg);
    console.log('Data processing completed.');
    return result;
  };
}

// 原始处理函数
function mainHandler(data) {
  console.log('Main handler:', data);
  // 执行主要的业务逻辑
  return data;
}

const pipeline = compose(loggerMiddleware, authorizationMiddleware, dataProcessingMiddleware);

const result = pipeline(mainHandler)('Data to be processed');
console.log(result); // 输出:Data to be processed

在这个示例中,我们定义了三个中间件函数:loggerMiddleware用于记录日志,authorizationMiddleware用于进行授权,dataProcessingMiddleware用于数据处理。然后,我们定义了一个原始处理函数mainHandler,它是整个处理流程的入口。使用compose函数,我们将这三个中间件按照顺序组合成一个处理管道pipeline。最后,我们将mainHandler作为参数传递给pipeline,并传入待处理的数据'Data to be processed',得到最终的结果。