全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-16 8 分钟 ✍️ juanwangdev

JavaScript 函数式编程

函数式编程强调纯函数、不可变数据和函数组合,代码更易测试和推理。

纯函数

相同输入永远返回相同输出,无副作用:

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

// 非纯函数(依赖外部状态)
let counter = 0;
function increment() {
  counter++;  // 副作用
  return counter;
}

// 非纯函数(修改输入)
function addItem(arr, item) {
  arr.push(item);  // 修改原数组
  return arr;
}

不可变性

避免直接修改数据,返回新副本:

JavaScript
// 可变方式(不推荐)
const user = { name: 'Alice', age: 25 };
user.age = 26;

// 不可变方式(推荐)
const updatedUser = { ...user, age: 26 };

// 数组不可变操作
const arr = [1, 2, 3];
const newArr = [...arr, 4];        // 添加
const filtered = arr.filter(x => x !== 2);  // 删除
const mapped = arr.map(x => x * 2); // 修改

深拷贝工具

JavaScript
// 简单深拷贝
const deepClone = obj => JSON.parse(JSON.stringify(obj));

// 结构化克隆
const cloned = structuredClone(obj);

柯里化

将多参数函数转为单参数链式调用:

JavaScript
// 手动柯里化
function curry(fn) {
  return function curried(...args) {
    return args.length >= fn.length
      ? fn(...args)
      : (...more) => curried(...args, ...more);
  };
}

// 示例
const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);

curriedAdd(1)(2)(3);  // 6
curriedAdd(1, 2)(3);  // 6

函数组合

将多个函数串联执行:

JavaScript
// pipe: 从左到右
const pipe = (...fns) => x => fns.reduce((v, fn) => fn(v), x);

// compose: 从右到左
const compose = (...fns) => x => fns.reduceRight((v, fn) => fn(v), x);

// 使用
const double = x => x * 2;
const addOne = x => x + 1;
const toString = x => String(x);

const transform = pipe(double, addOne, toString);
transform(3);  // "7" (3 * 2 + 1)

高阶函数模式

偏函数应用

JavaScript
const partial = (fn, ...presetArgs) => (...laterArgs) =>
  fn(...presetArgs, ...laterArgs);

const multiply = (a, b, c) => a * b * c;
const double = partial(multiply, 2);

double(3, 4);  // 24

记忆化

JavaScript
const memoize = fn => {
  const cache = new Map();
  return (...args) => {
    const key = JSON.stringify(args);
    if (!cache.has(key)) {
      cache.set(key, fn(...args));
    }
    return cache.get(key);
  };
};

const factorial = memoize(n => {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
});

常用函数式工具

map/filter/reduce

JavaScript
const numbers = [1, 2, 3, 4, 5];

// 链式调用
numbers
  .filter(x => x % 2 === 0)
  .map(x => x * 2)
  .reduce((sum, x) => sum + x, 0);  // 12

函数式链式操作

JavaScript
// 无需中间变量的数据处理
const result = [1, 2, 3, 4, 5]
  .filter(x => x > 2)
  .map(x => x * x)
  .reduce((a, b) => a + b, 0);  // 50

函数式 vs 命令式

JavaScript
// 命令式
const doubled = [];
for (let i = 0; i < arr.length; i++) {
  doubled.push(arr[i] * 2);
}

// 函数式
const doubled = arr.map(x => x * 2);
特点命令式函数式
关注点如何做做什么
状态可变不可变
副作用允许避免
测试较难容易

要点总结

  • 纯函数无副作用,相同输入必返回相同输出
  • 不可变性通过返回副本实现,避免直接修改
  • 柯里化将多参数转为单参数链式调用
  • pipe/compose 实现函数组合
  • 函数式代码更易测试、推理和并行

📝 发现内容有误?点击此处直接编辑

← 上一篇 JavaScript 代理与反射(Proxy/Reflect)
下一篇 → JavaScript 原型链
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库