函数式编程
架构设计另一个编程范式—函数式编程,其主要关心数据到数据之间的映射关系,即将计算过程抽象描述成一种表达式求值。先看下以下实现数组转换成数组对象的函数代码:
// 实现数组转换数组对象
function AryToObjectAry() {
const ary = ["jasen-yang", "tom-han", "marry-han", "lucy-any"];
const newObj = [];
ary.forEach((value) => {
let names = value.split("-");
let newNames = [];
names.forEach((name) => {
const temp = name[0].toUpperCase() + name.slice(1);
newNames.push(temp);
});
newObj.push({ name: newNames.join(" ") });
});
console.log(newObj);
return newObj;
}
(()=>{
AryToObjectAry()
})();
// 输出结果
[
{ name: 'Jasen Yang' },
{ name: 'Tom Han' },
{ name: 'Marry Han' },
{ name: 'Lucy Any' }
]
定义变量,循环数组,把值开头大写,每个函数各司其职,按一定的步骤,从函数输入到输出结果。从代码上阅读可以很清楚知道在做什么,但是一但出问题就很难定位,其中掺杂了大些逻辑和变量。
如果每个过程都是一个函数,会怎么样?看下以下伪代码:
function convertAry() {
const ary = ["jasen-yang", "tom-han", "marry-han", "lucy-any"];
const getNames = (value) => {
return value.split("-");
};
const toUpper = (value) => {
return value[0].toUpperCase() + value.slice(1);
};
const convertName = (newObj,value) => {
return newObj.push({ name: value });
};
const newObj = [];
ary.forEach((value)=>{
const newName = compose(getNames(value),toUpper);
const result = compose(newObj,convertName(newName));
});
return newObj;
}
看整个编程思路,可以清晰看出,函数式编程,重点是函数而不是过程,通过函数的组合变换去解决问题。每个函数可以看出在做什么,一目了然,函数让代码更加语义化,可读性更高。
函数式编程,重点是在构建关系,通过构建一条高效的流水线,一次解决所有的问题,而不是关注各个函数之间的数据。
函数式编程特点
函数式一等公民
在函数式编程中,变量是不能被修改的,所有的变量只能被赋值一次,所有的值全都靠传参来解决的。函数作为一等公民,可以在任何地方定义,可以作为参数和返回值,可以对函数进行组合。
无状态和数据不可变
函数式编程的核心
- 数据不可变,若修改一个对象,应建一个新对象而不是修改已有的对象
- 无状态,对于一个函数,无论何时运行,在给定的相同输入都能输出相同结果,完全不依赖外部状态的变化
惰性执行
函数只在需要的适合执行,不产生无意义的中间变量。比如,在处理过程中都在写函数,而只有在最后才去产生实际的结果。
参考资料
\