函数式
一、 函数式编程的出现
- 编码发展历程: 命令(脚本)式 =》面向对象(进一步提高了模块的概念)=》函数式编程
1. 问题的出现 -面试题
const _array = ['Progerssive Coding', 'Objective Coding', 'Function Coding']
const _objArr = []
const nameParser = () => {
array.forEach(item => {
let names = item.split('$%')
let newName = []
names.forEach(name => {
let nameItem = name[0].toUpperCase() + name.slice(1)
newNames.push(nameItem)
})
})
objArr.push({
name: newName.join(' ')
})
return objArr
}
console.log(nameParser(_array, _objArr))
2.解决方案
const _array = ['Progerssive$%Coding', 'Objective$%Coding', 'Function$%Coding']
const assembleObj = (key, x) => {
let obj = {}
obj[key] = x
return obj
}
const capitalize = name => name[0].toUpperCase() + name.splice(1)
const formatName = 组装合并(join(''), map(capitalize), split('$%'))
const objHelper = 组装合并(assmebleObj('name'), formatName)
const nameParser = map(objHelper)
nameParser(_array)
let class = 'functional'
let isOvered = false
classArr.forEach(item => {
isOvered = item === class
})
二、函数式编程的原理特点
1.什么是函数式编程的原理
- 加法结合律 因式分解 完全平方公式 这三者其实在描述一个原子组合的变化 原子操作组合方式做了改变
- 水源 =》 (水管+走线)=》浴缸
2.理论思想
a. 函数是一等公民 函数是实实在在的逻辑功能实现的落脚点 在过程式编程中并不是每行代码都有功能 (实现+拼接)*函数
b. 声明式编程 声明需求 语义化 更像是语言在描述需求 react vue3 就是通过一个一个独立的纯函数钩子,在内部做一些独立的子需求模块
c. 惰性执行
const program = name => {
if (name === 'progressive') {
return program = () ={
console.log('progressive')
}
} else if (name === 'objective') {
return program = () ={
console.log('objective')
}
} else {
return program = () ={
console.log('functional')
}
}
}
program('progressive')()
console.log('lazy')
program()
3.无状态与无副作用
- 无状态 - 幂等 - 数据不可变 函数内部坚决不可以直接操作整个系统中的任何参数变量的数据
三、实际开发
1.纯函数改造
const _class = {
name: 'objective'
}
const score = str => _class.name + ':' + str
const changeClass = (obj, name) => obj.name = name
changeClass(_class, 'functional')
score('good!')
const _class = {
name: 'objective'
}
const score = (obj, name) => obj.name + ':' + str
const changeClass = (obj, name) => ({...obj, name})
changeClass(_class, 'functional')
score(_class, 'good')
2 流水线组装 加工 组装
const sum = (x, y) => {
return x+y
}
sum(1,2)
const add = x => {
return y => {
return x + y
}
}
add(1)(2)
const fetch = ajax(method, url, params)
const request = ajax(method)
const fetch = request(url)
ajax(method)(url)(params)
- 面试题: 手写构造可拆分传参的累加函数
add(1)(2)(3)
const add = function () {
let args = Array.prototype.slice.call(arguments)
let inner = function () {
args.push(...arguments)
return inner
}
inner.toString = function () {
return args.reduced((pre, cur) => {
return prev + cur
})
}
return inner
}
add(1)(2)(3)(4)
b.流水线
const compose = (f, g) => x => f(g(x))
const sum1 = x => x + 1
const sum2 = x => x + 2
const sum12 = compose(sum1, sum2)
sum12(1)
trim(reverse(toUpperCase(map(arr))))
arr.map().toUpperCase().reverse().trim()
const result = compose(trim, reverse, toupperCase, map)
pipe(map, toUpperCase, reverse, trim)
四、BOX与函子
class Mail {
constructor (content) {
this.content = content
}
map (fn) {
return new Mail(fn(this.content))
}
}
let mail1 = new Mail('love')
let mail2 = mail1.map(function(fn) {
return read(mail)
})
let mail3 = mail.map(function(mail) {
return burn(mail)
})
mail3.map(function(mail) {
return check(mail)
})
new Mail('love').map(read).map(burn).map(check)