你不知道的 JS 编程范式

242 阅读3分钟

image.png

JS 都有哪些范式

JavaScript 是一种多范式编程语言,它支持多种编程范式,包括但不限于以下几种:

  1. 声明式编程(Declarative Programming):通过声明和表达式来描述程序应该完成的任务,而不关注具体实现。常见的声明式编程范式有函数式编程和逻辑编程。
  2. 命令式编程(Imperative Programming):通过详细描述计算机如何执行任务的步骤来编写程序。这种范式通常使用变量、赋值、条件语句和循环等。
  3. 面向对象编程(Object-oriented Programming, OOP):通过抽象和封装将数据和操作数据的方法组织在一起的编程范式。在 JavaScript 中,可以使用类、原型和对象等概念来实现面向对象编程。
  4. 函数式编程(Functional Programming, FP):把计算看作是数学函数的求值,强调函数的组合、无副作用和不可变性。JavaScript 中支持高阶函数、闭包、柯里化等函数式编程概念。
  5. 事件驱动编程(Event-driven Programming):程序的执行流程由事件触发,例如用户操作、消息传递等。在 JavaScript 中,可以使用事件监听器和事件处理函数来实现事件驱动编程。
  6. 响应式编程(Reactive Programming):处理异步数据流的编程范式,通过观察者模式将数据源和消费者连接起来。在 JavaScript 中,可以使用响应式编程库,例如 RxJS,来实现响应式编程。

JavaScript 的灵活性使得这些范式可以单独使用,也可以混合使用。开发者可以根据实际需求和编程风格选择适合的编程范式。

举例

为了说明这些范式的不同之处,让我们考虑一个简单的任务:计算一个整数数组中所有偶数的和。

  1. 声明式编程 (Declarative Programming)

声明式编程关注任务的结果,而不是具体的实现过程。在这个例子中,我们可以使用 JavaScript 的高阶函数 filterreduce

const numbers = [1, 2, 3, 4, 5, 6];
const evenSum = numbers.filter(x => x % 2 === 0).reduce((acc, val) => acc + val, 0);
console.log(evenSum); // 输出: 12
  1. 命令式编程 (Imperative Programming)

命令式编程关注具体的实现过程,需要明确的控制结构和操作:

const numbers = [1, 2, 3, 4, 5, 6];
let evenSum = 0;

for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] % 2 === 0) {
    evenSum += numbers[i];
  }
}

console.log(evenSum); // 输出: 12
  1. 面向对象编程 (Object-oriented Programming, OOP)

面向对象编程将数据和对数据的操作封装在类或对象中:

class NumberArray {
  constructor(numbers) {
    this.numbers = numbers;
  }

  evenSum() {
    return this.numbers.filter(x => x % 2 === 0).reduce((acc, val) => acc + val, 0);
  }
}

const numbers = new NumberArray([1, 2, 3, 4, 5, 6]);
console.log(numbers.evenSum()); // 输出: 12
  1. 函数式编程 (Functional Programming, FP)

函数式编程通过函数组合、无副作用和不可变性来表达计算:

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

const isEven = x => x % 2 === 0;
const sum = (acc, val) => acc + val;

const evenSum = numbers.filter(isEven).reduce(sum, 0);
console.log(evenSum); // 输出: 12
  1. 事件驱动编程 (Event-driven Programming)

事件驱动编程通过监听和处理事件来完成任务。在这个例子中,我们可以使用一个事件触发器来计算偶数和:

const EventEmitter = require('events');

class Calculator extends EventEmitter {
  evenSum(numbers) {
    this.emit('evenSum', numbers.filter(x => x % 2 === 0).reduce((acc, val) => acc + val, 0));
  }
}

const calculator = new Calculator();
calculator.on('evenSum', (result) => console.log(result));

const numbers = [1, 2, 3, 4, 5, 6];
calculator.evenSum(numbers); // 输出: 12
  1. 响应式编程 (Reactive Programming)

响应式编程处理异步数据流。在这个例子中,我们可以使用 RxJS 库来计算偶数和:


const { from } = require('rxjs');
const { filter, reduce } = require('rxjs/operators');

const numbers = [1, 2, 3, 4, 5, 6];
const numbers$ = from(numbers);

numbers$
  .pipe(
    filter(x => x % 2 === 0),
    reduce((acc, val) => acc + val, 0)
  )
  .subscribe(evenSum => console.log(evenSum)); // 输出: 12

上述示例中,我们使用了不同的编程范式来实现相同的功能:计算整数数组中所有偶数的和。每种范式都有其特点和适用场景,开发者可以根据需求和编程风格选择合适的范式。