函数式编程(Functional Programming,简称 FP),通过对面向对象式编程代码的拆分,将各个功能独立出来,从而达到功能独立、易复用等目的。
举例:代码转换
[‘john-reese’, ‘harold-finch’, ‘sameen-shaw’]
转换成
[{
name: 'John Reese'
}, {
name: 'Harold Finch'
}, {
name: 'Sameen Shaw'
}]
对上面代码进行转换。
(1)拆分数组中字符串,将字符串变成人名。john-reese -> John Reese
(2)将数组转换成对象。[‘John Reese’] -> [{ name: ‘John Reese’ }]
/**
* @name 改变人名展示方式
* @param {array} arr 需要改变的数组
* @param {string} type 支持不同格式的人名
*/
const changeName = (arr, type) => {
// map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
// map() 方法按照原始数组元素顺序依次处理元素。
// 注意: map() 不会对空数组进行检测。
// 注意: map() 不会改变原始数组。
// split() 方法用于把一个字符串分割成字符串数组。
// toUpperCase() 方法将字符串小写字符转换为大写。
return arr.map(item => item.split(type).map(name => name[0].toUpperCase() + name.slice(1)).join(' '));
};
/**
* @name 数组改变成对象
* @param {array} arr 需要改变的数组
* @param {string} key 对应变成什么字段
* @return {object} 返回改变后的对象
*/
const arrToObj = (arr, key) => {
return arr.map(item => ({
[key]: item
}));
};
const result = arrToObj(changeName(['john-reese', 'harold-finch', 'sameen-shaw'], '-'), 'name');
console.log(result); // [ { name: 'John Reese' },{ name: 'Harold Finch' }, { name: 'Sameen Shaw' } ]
函数式编程就是对可以抽离的功能都进行抽取封装。
函数式编程特点
- 函数是一等公民。 可以利用这点让它支持抽取到外部。
- 声明做某件事件。 函数式编程大多数声明某个函数需要做什么, 而不是它怎么做的。
- 便于垃圾回收。 函数内部的变量方便垃圾回收, 不会产生太多的变量, 用户不需要大量的定义。
- 数据不可变。 函数式编程要求所有的数据都是不可变的, 如果需要修改某个对象, 应该新建后再修改, 而不是污染原本的数据。
- 无状态。 不管什么时候运行, 同一个函数对相同的输入返回相同的输出, 而不依赖外部状态的变化。
- 无副作用。 功能 A 应该仅仅为了完成它的实现, 而不会随着外部的改变而改变, 这样当它执行完毕之后, 就可以将其内部数据进行回收。 并且它不会修改传入的参数。
注重引用值( Object、 Array) 的传递, 尽可能不要污染传入的数据。
纯函数
纯函数的概念有 2 点:
不依赖外部状态( 无状态): 函数的运行结果不依赖全局变量, this 指针, IO 操作等。
没有副作用( 数据不变): 不修改全局变量, 不修改入参。
优点:
便于测试和优化
可缓存性
自文档化
更少 Bug
关于纯函数可参考:https://blog.csdn.net/c_kite/article/details/79138814