Skip to content

函数式编程

什么是函数式编程?

函数式编程是一种编程范式,它将计算视为数学函数的求值,避免状态变更和可变数据。

函数式编程的核心原则

  1. 纯函数:相同的输入总是产生相同的输出,没有副作用
  2. 不可变数据:数据一旦创建就不能修改
  3. 函数是一等公民:函数可以作为参数传递,作为返回值,存储在变量中
  4. 高阶函数:接受函数作为参数或返回函数的函数
  5. 递归:使用递归代替循环
  6. 函数组合:将多个简单函数组合成复杂函数

纯函数

纯函数的特点

  • 无副作用:不修改外部状态或变量
  • 确定性:相同输入总是产生相同输出
  • 可测试性:容易编写单元测试
  • 可缓存性:可以缓存结果提高性能

纯函数示例

javascript
// 纯函数
function add(a, b) {
  return a + b;
}

// 非纯函数(修改了外部变量)
let total = 0;
function addToTotal(value) {
  total += value; // 副作用:修改了外部变量
  return total;
}

// 非纯函数(依赖外部状态)
function getRandomNumber() {
  return Math.random(); // 副作用:依赖外部状态
}

不可变数据

为什么使用不可变数据?

  • 减少副作用
  • 避免意外修改
  • 提高代码可预测性
  • 便于调试和测试

实现不可变数据的方法

javascript
// 使用 Object.freeze()
const person = Object.freeze({ name: 'Alice', age: 30 });

// 函数式更新对象
function updateName(person, newName) {
  return { ...person, name: newName };
}

// 函数式更新数组
function addItem(array, item) {
  return [...array, item];
}

function removeItem(array, index) {
  return [...array.slice(0, index), ...array.slice(index + 1)];
}

高阶函数

常见的高阶函数

  • map:将数组中的每个元素映射到新值
  • filter:过滤数组中的元素
  • reduce:将数组归约为单个值
  • forEach:遍历数组
  • find:查找符合条件的元素
  • some:检查是否有元素符合条件
  • every:检查是否所有元素都符合条件

高阶函数示例

javascript
// 自定义高阶函数
function withLogging(fn) {
  return function(...args) {
    console.log('Calling function with arguments:', args);
    const事情 = fn(...args);
    console.log('Function returned:', result);
    return result;
  };
}

const addWithLogging = withLogging((a, b) => a + b);
addWithLogging(2, 3); // 输出: Calling function with arguments: [2, 3], Function returned: 5

函数组合

函数组合的概念

函数组合是将多个函数连接起来,前一个函数的输出作为后一个函数的输入。

函数组合示例

javascript
// 简单的函数组合
function compose(f, g) {
  return function(x) {
    return f(g(x));
  };
}

// 使用函数组合
const toUpperCase = str => str.toUpperCase();
const exclaim = str => str + '!';
const shout = compose(exclaim, toUpperCase);