解决什么问题

人工智能、区块链、AR、VR、新零售等业务场景的出现,产品界面交互正在变得越来越复杂,需要快速、正确、高效地开发出高复杂度页面。

FP 有什么特点

JS 语言中的函数不同于 Java ,C/C++ 等语言, 可以被当做参数和返回值进行传递

  • 函数为一等公民

  • 模块化、组合

  • 引用透明

  • 避免状态改变

  • 避免共享状态

案例

分别实现数组所有元素相加、相乘、相与?

非 FP 风格
  1. function plus(array) {
  2. var res = array[0];
  3. for (let i = 1; i < array.length; i++) {
  4. res += array[i];
  5. }
  6. }
  7. function mul(array) {
  8. var res = array[0];
  9. for (let i = 1; i < array.length; i++) {
  10. res *= array[i];
  11. }
  12. }
  13. function and (array) {
  14. var res = array[0];
  15. for (let i = 1; i < array.length; i++) {
  16. res = res & array[i];
  17. }
  18. }
  19. plus(array);
  20. mul(array);
  21. and(array);

FP 风格
  1. var ops = {
  2. "plus": (x,y)=>x+y,
  3. "mul" : (x,y)=>x*y,
  4. "and" : (x,y)=>x&y
  5. }
  6. function operation(op, array) {
  7. return array.slice(1).reduce(ops[op], array[0]);
  8. }
  9. operation("plus", array);
  10. operation("mul", array);
  11. operation("and", array);

React 的 FP

React 框架中,当用户操作 UI 或者 API 的返回带来了数据的改变,React 随即进行 virtual dom diff 计算得到 dom 的修改指令,对 dom 元素应用修改指令便得到最新的 html 界面,如下图所示:
Function Programming - 图1
不难发现,React 其实是应用数据对UI的一种映射,不同的数据会映射出不同样式的 UI 界面,我们可以得出如下的表达式:Function Programming - 图2

没错,React 的本质其实是一种函数,并且还是符合 FP 要求的“引用透明”函数。所谓“引用透明”就是指函数的输出仅依赖函数参数,不受任何外部环境影响。这样的函数可测试性强,也非常容易进行组合。

在 React 的体系下,任何组件都可由一个个更小的组件构成,每个组件都只关心自己的输入,他们不断地接受新的数据并输出对应的新的UI界面。React 框架中常用的“高阶组件”可以看作引用透明”函数的组合模式。

在具体业务中我们通常还需要权衡 React 组件的复用性和开发体验,如果组件被拆分的过于细,固然复用性会提升,但文件数量会增加,对应的文档和沟通成本也会增加,这也是 FP 在实践过程中经常遭人诟病的点,即复用性提升后带来的额外开发成本。