JavaScript 函数式编程:基础与实践

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

JavaScript 函数式编程入门



函数式编程(FP)是一种将计算视为数学函数应用的编程范式。与编写一系列改变程序状态的指令的命令式方法不同,函数式风格关注的是需要计算什么,而不是如何计算。



JavaScript 作为一种多范式语言,非常适合函数式编程。在 Node.js 环境中,这种方法对于数据处理、流操作以及构建可靠的服务器端应用尤其有用。本文将通过实际示例解析函数式编程的核心概念。



函数式编程的核心原则



纯函数

纯函数是指:

  • 相同的参数始终返回相同的结果(确定性)。
  • 没有副作用(不修改外部变量,不向控制台输出,不写入文件)。


// Pure functionconst add = (a, b) => a + b;

// Impure function (side effect — console output)const impureAdd = (a, b) => { console.log(`Adding ${a} and ${b}`); return a + b;};

// Impure function (depends on external state)let counter = 0;const increment = () => ++counter;


纯函数的优点:易于测试、调试和并行化。它们是可预测的,且不依赖于执行上下文。



不可变性

不可变性意味着数据一旦创建就不能被改变。我们不是修改现有对象,而是创建一份带有所需更改的新副本。



// Mutable approach (bad)const user = { name: 'Ivan', age: 30 };user.age = 31; // Directly modifying

// Immutable approach (good)const user2 = { name: 'Maria', age: 25 };const updatedUser = { ...user2, age: 26 };// The original user2 object remains unchanged

// Working with arraysconst numbers = [1, 2, 3];const newNumbers = [...numbers, 4]; // [1, 2, 3, 4]// numbers remains [1, 2, 3]


在 Node.js 中,不可变性在处理请求和应用状态时尤其重要,可以避免异步代码中出现意外的修改。



高阶函数与闭包



高阶函数

这些函数接受其他函数作为参数或返回函数。内置数组方法 map、filter 和 reduce 是经典例子。



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

// map — transforms each elementconst doubled = numbers.map(n => n * 2);// [2, 4, 6, 8, 10]

// filter — keeps elements based on a conditionconst evens = numbers.filter(n => n % 2 === 0);// [2, 4]

// reduce — reduces the array to a single valueconst sum = numbers.reduce((acc, n) => acc + n, 0);// 15


闭包

闭包是一个函数,它"记住"了创建时所在作用域中的变量,即使该作用域已执行完毕。



const createCounter = () => {    let count = 0; // Private variable    return () => ++count;};

const counter1 = createCounter();console.log(counter1()); // 1console.log(counter1()); // 2

const counter2 = createCounter();console.log(counter2()); // 1 (independent counter)


闭包被广泛用于创建函数工厂以及以函数式风格封装状态。



柯里化与函数组合



柯里化

柯里化是将一个接受多个参数的函数转换为一系列函数的过程,每个函数接受一个参数。

博客

书籍推荐