Skip to content

编程范式

编程范式就是编程风格,主流的有命令式、函数式(属于声明式)、面向对象等。JavaScript 是一种多范式编程语言,支持多种编程范式,允许开发者根据需求选择适合的编程风格。

命令式

通过一系列命令(或语句)来改变程序的状态。命令式编程的核心思想是:告诉计算机做什么以及如何做。
命令式也是新手学习编程的最简单方式。

特点

  • 状态管理:命令式编程通过变量的状态变化来表示程序的当前状态。
  • 顺序执行:代码按照编写的顺序逐行执行。
  • 可变性:变量的值可以在程序执行的过程中被多次修改。
  • 副作用:命令式编程中,函数的执行会产生副作用,即函数执行后会影响到程序的其他部分。
javascript
let sum = 0
for (let i = 1; i <= 10; i++) {
  sum += i
}
console.log(sum) // 输出 55

在这个例子中,sum 的值在每次循环时都发生变化,这是典型的命令式编程风格。

函数式

程序主要由函数的组合而成。它强调函数的应用和函数之间的组合,尽量避免状态变化和副作用。

特点

  • 函数是"第一等公民"
    所谓"第一等公民"(first class),指的是函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。

  • 只用"表达式",不用"语句"

    • "表达式"(expression)是一个单纯的运算过程,总是有返回值;
    • "语句"(statement)是执行某种操作,没有返回值。
      函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。
  • 没有"副作用"
    所谓"副作用(side effect)",指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。 函数式编程强调没有"副作用",意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。

  • 不修改状态
    上一点已经提到,函数式编程只是返回新的值,不修改系统变量。因此,不修改变量,也是它的一个重要特点。 在其他类型的语言中,变量往往用来保存"状态"(state)。不修改变量,意味着状态不能保存在变量中。函数式编程使用参数保存状态,最好的例子就是递归。

  • 引用透明(Referential transparency) 指的是函数的运行不依赖于外部变量或"状态",只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的。

特征

  • 纯函数:函数式编程中的函数通常是“纯函数”,即相同的输入总是产生相同的输出,且没有副作用。
  • 不可变性:状态和数据通常是不可变的,即一旦创建就不能改变。
  • 高阶函数:函数可以作为参数传递给其他函数,或者作为返回值从函数中返回。
  • 函数组合:通过组合简单的函数来构建复杂的行为。
javascript
const numbers = [1, 2, 3, 4, 5]
const doubledNumbers = numbers.map((n) => n * 2)
console.log(doubledNumbers) // 输出 [2, 4, 6, 8, 10]

在这个例子中,map 函数是一个高阶函数,它接受一个函数作为参数,并返回一个新数组,这是函数式编程的典型用法。

面向对象

面向对象编程通过“对象”来组织代码。对象是具有状态(属性)和行为(方法)的实体。面向对象编程的核心概念包括类、对象、继承和多态等。

  • 封装:将数据和操作数据的方法封装在对象内部,隐藏对象的内部实现。
  • 继承:通过继承机制,子类可以继承父类的属性和方法,促进代码的重用。
  • 多态:不同的对象可以以统一的接口来实现不同的行为。
  • 对象:对象是类的实例,它包含了类定义的属性和方法。
javascript
class Animal {
  constructor(name) {
    this.name = name
  }

  speak() {
    console.log(`${this.name} makes a noise.`)
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} barks.`)
  }
}

const dog = new Dog('Rex')
dog.speak() // 输出 'Rex barks.'

在这个例子中,我们定义了一个 Animal 类和一个继承自它的 Dog 类。Dog 类重写了 speak 方法,这是面向对象编程中多态的体现。

总结

  • 命令式编程 强调如何去做,通过明确的步骤来管理状态和执行任务。
  • 函数式编程 强调声明性的代码,通过函数的组合来实现复杂的逻辑,避免可变状态和副作用。
  • 面向对象编程 通过对象和类来组织代码,强调数据和行为的封装与继承。-

提示

在我看来,函数式更加接近计算机科学的本质,更加抽象。命令式更加接近人类的思维方式,更加直观。而面向对象更加接近现实世界的实体,更加具体。 个人比较偏函数式,故此文会持续更新函数式的更多用法。

参考资料

君子慎独