【前端进阶】很多前端都不懂的[functor]!你懂你就领先一步了!

1,231 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文同时参与 「掘力星计划」        ,赢取创作大礼包,挑战创作激励金

functor(函子)

functor的英文解释为something that performs a function,即其行为类似函数的东西。

为什么要学 functor

到目前为止已经学习了函数式变成的一些基础(详细查看往期),但是我们还没有演示在函数式编程中如何把副作用控制在可控的范围内、异常处理、异步操作等。

往期

什么是functor

  • 容器:包含值和值的变形关系(这个变形关系就是函数)
  • 函子:是一个特殊容器,通过有个普通的对象来实现,该对象具有map方法,map方法可以运行一个函数对值进行处理(变形关系)

这个解释了什么东西啊? ceeb653ely1gam2j9ym3tg20dc0cmab5.gif 别急,往下看,我们一点一点来进行模拟!

让我们用代码来演示一下

  1. 函子是一个普通的对象(容器),这个对象要维护一个值,并对外暴露出map方法,因此我们要定义一个类来描述函子
class Container {
    
}
  1. 在我们创建这个函子的时候,它内部需要有一个值,所以我们在构造函数的时候需要传入我们要给函子的值
class Container {
    construtor(value){
        this._value = value
    }
}
  1. 对外公布一个map方法,map方法的作用是接收一个处理值的函数,这个函数也是一个纯函数,且要处理这个函数,并返回一个新盒子也就是新函子
class Container {
    construtor(value){
        this._value = value
    }
    map(fn){
        return new Container(fn(this._value))
    }
}
  1. 我们创建一下函子对象
new Container(5).map(x => x + 1)
// 因为函子对象的map方法发挥了新的函子对象 那我们还可以这样处理
new Container(5).map(x => x + 1).map(x => x + 2 ) // Container { _value: 8 }

不使用new操作符怎么写?

我们可以用类的静态方法来进行处理,创建一个静态方法传入对应的参数,到时候我们就可以直接通过Container.[静态方法名] 来进行调用

class Container {
  static of (value) {
    return new Container(value)
  }
  constructor (value) {
    this._value = value
  }
  map (fn) {
    return Container.of(fn(this._value))
  }
}
let r = Container.of(5).map(x => x + 1).map(x => x + 2 ) // Container { _value: 8 }

【注意】:map方法始终返回的是一个对象,我们的值不对外进行暴露,如果想要对值进行修改,就需要传入对应的修改方法

总结

  • 函数式编程运算不直接操作值,而是由函子完成
  • 函子就是实现了map契约的对象
  • 我们可以把函子想象成一个盒子,这个盒子封装了一个值
  • 想要处理盒子中的值,我们需要给盒子的map方法传递一个处理值的纯函数(纯函数),由这个函数来对值进行处理
  • 最终map方法返回一个包含新值的盒子(函子)

一些小问题

我们使用我们之前写好的简单版函子,我们给他传入null

let test = new Container(null)
test.map(x => x.toUpperCse) // 报错

这里我们就稍微演示了一下函子的副作用,在下篇中,我们会进行处理一下,这个简单函子一些暴露出来的问题,都看到这里来,各位彦祖和亦菲给我点个赞吧,求求了! u=945999832,3434885325&fm=26&fmt=auto.webp