解决什么问题
人工智能、区块链、AR、VR、新零售等业务场景的出现,产品界面交互正在变得越来越复杂,需要快速、正确、高效地开发出高复杂度页面。
FP 有什么特点
JS 语言中的函数不同于 Java ,C/C++ 等语言, 可以被当做参数和返回值进行传递
函数为一等公民
模块化、组合
引用透明
避免状态改变
避免共享状态
案例
分别实现数组所有元素相加、相乘、相与?
非 FP 风格
function plus(array) {
var res = array[0];
for (let i = 1; i < array.length; i++) {
res += array[i];
}
}
function mul(array) {
var res = array[0];
for (let i = 1; i < array.length; i++) {
res *= array[i];
}
}
function and (array) {
var res = array[0];
for (let i = 1; i < array.length; i++) {
res = res & array[i];
}
}
plus(array);
mul(array);
and(array);
FP 风格
var ops = {
"plus": (x,y)=>x+y,
"mul" : (x,y)=>x*y,
"and" : (x,y)=>x&y
}
function operation(op, array) {
return array.slice(1).reduce(ops[op], array[0]);
}
operation("plus", array);
operation("mul", array);
operation("and", array);
React 的 FP
React 框架中,当用户操作 UI 或者 API 的返回带来了数据的改变,React 随即进行 virtual dom diff 计算得到 dom 的修改指令,对 dom 元素应用修改指令便得到最新的 html 界面,如下图所示:
不难发现,React 其实是应用数据对UI的一种映射,不同的数据会映射出不同样式的 UI 界面,我们可以得出如下的表达式:
没错,React 的本质其实是一种函数,并且还是符合 FP 要求的“引用透明”函数。所谓“引用透明”就是指函数的输出仅依赖函数参数,不受任何外部环境影响。这样的函数可测试性强,也非常容易进行组合。
在 React 的体系下,任何组件都可由一个个更小的组件构成,每个组件都只关心自己的输入,他们不断地接受新的数据并输出对应的新的UI界面。React 框架中常用的“高阶组件”可以看作引用透明”函数的组合模式。
在具体业务中我们通常还需要权衡 React 组件的复用性和开发体验,如果组件被拆分的过于细,固然复用性会提升,但文件数量会增加,对应的文档和沟通成本也会增加,这也是 FP 在实践过程中经常遭人诟病的点,即复用性提升后带来的额外开发成本。