JavaScript函数式编程是用原生能力实现“输入→纯函数→输出”的链式表达,强调不改原始数据、无副作用、易测试复用;纯函数要求相同输入恒得相同输出,避免修改外部状态或触发副作用。
JavaScript 函数式编程不是一种新语言,而是用 const、=>、map、filter、reduce 这些原生能力,把逻辑写成“输入 → 纯函数 → 输出”的链式表达。它不改变原始数据,也不依赖外部状态,所以更容易预测、测试和复用。
纯函数指:相同输入永远返回相同输出,且不修改外部变量或触发副作用(比如改 document、发请求、改入参对象)。
arr.sort() 直接修改原数组,后续逻辑可能意外拿到已排序的引用 —— 改用 [...arr].sort() 或 arr.toSorted()(ES2025)才符合纯函数习惯const getTotal = (items) => items.reduce((sum, i) => sum + i.price, 0),而不是在函数里 push 到某个全局数组lodash.memoize),但要注意参数是引用类型时需深比较,否则缓存失效JS 原生不强制不可变,靠约定 + 工具约束。关键不是“完全禁止赋值”,而是避免意外覆盖。
const obj = { a: 1 }; obj.a = 2; 合法但破坏了不可变性;应改用 { ...obj, a: 2 } 或 Object.assign({}, obj, { a: 2 })
Array.prototype.map 返回新数组,Array.prototype.forEach 不返回、常用于副作用 —— 优先选 map,除非你明确需要发请求或打日志toSorted()、toReversed()、with() 是 ES2025 新增的不可变数组方法,旧环境需 polyfill 或用展开运算符替代把函数当参数传、或返回函数,就能把逻辑拆细、再拼装。这不是炫技,是为应对变化。
filterActive、formatName、addRole 三个纯函数,再用 pipe 组合pipe 就够用:const pipe = (...然后fns) => (x) => fns.reduce((v, f) => f(v), x);
pipe(filterActive, formatName, addRole)(users)
真正难的不是学会 map 和 reduce,而是在团队协作中坚持“不改入参”“不读全局变量”“副作用集中到最外层”。一旦有人在中间步骤 push 到共享数组,整条函数链就退化成命令式代码 —— 这种隐性破坏,比语法错误更难排查。