在JavaScript中亦存在MayBe函子的设计,按
F12
在控制台尝试输入new Array(6).map(v => console.log(v)
试试console.log
是否执行了
🍐 函子即容器
在函数式编程中,函子是一个常见的概念。简单来说,函子是一个持有值的容器对象(通常通过类实现),其核心特性是具有map
方法。map
方法的作用是将一个函数应用到容器中的值,并返回一个新的函子对象,容器内部的值被映射为新值。这种设计使得我们可以方便地链式处理数据,且保持不可变性。
🍐 简单实现
1 | class Container { |
在上面的代码中,我们定义了一个Container
类,它持有一个值value
。类内部的map
方法接受一个函数fn
,将该函数应用到value
上,最终返回一个新的Container
对象。通过static of
方法,我们可以将任意值包装成一个新的Container
对象,从而形成函子
🍐 Pointed 函子
所谓Pointed
函子,是指那些除了实现map
方法外,还实现了of
静态方法的函子。of
方法允许我们从一个普通值创建一个函子。这样的函子不仅能进行map
操作,还能从值的角度“指向”一个容器。因此,具备of
方法的函子可以被称为Pointed
。
🌰 函子使用
1 | const double = (n) => n * 2 |
🍐 MayBe 函子:空值处理
MayBe
函子是一个特殊的函子,它在普通函子的基础上增加了对空值的处理。我们可以用它来表示可能包含值,也可能为空的情形(如null
或undefined
)。通过MayBe函子,只有在容器中的值存在时,map
方法才会执行操作,否则返回一个空的MayBe
容器。
1 | class MayBe { |
在这个实现中,MayBe
容器有一个map
方法,在执行map
时,它首先会检查容器中的值是否为空。如果为空,map
方法直接返回一个空的MayBe
对象,否则将值传递给函数并返回一个新的MayBe
容器。
🌰 MayBe函子 使用
1 | const strVal = new MayBe('cool').map((v) => v.toUpperCase()) // MayBe { value: "COOL" } |
上面的示例展示了如何使用MayBe
函子来安全地处理可能为空的值。对于空值(如null
),map方法会直接返回一个空容器。
🌰 MayBe函子:处理复杂数据
假设我们需要从一个API返回的数据中获取某个字段。这个数据可能会有不同的结构,包括空数据或缺失字段。我们可以利用MayBe
函子链式地提取所需的值,从而避免重复的空值检查。
- 情况1:预期数据
1 | const result1 = { |
- 情况2: children为空
1 | const result2 = { |
- 情况3:获取到空数据
1 | const result3 = { |
🌰 使用函子去获取最后一个章节的id
1 | /** 获取最后一个章节的id */ |
在这个例子通过MayBe
函子链式地从复杂的数据结构中提取最后一章的ID。无论数据是否完整或是否为空,可以避免重复检查null
或undefined
,让代码更加简洁和安全。