持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情 函数式编程FP
编程范式分为
1.面向对象
2.面向过程和
3.函数式编程
函数式编程就是用函数表达事物之间关系。 对应数学中的 y = f(x) 用f来表示x和y之间的关系
javascritp中函数是一等公民(First-class Function),因为函数可以当做参数传递,可以当做值返回, 同样也可以用变量存储。
高阶函数
函数作为返回值,或者作为参数
// once
function once (fn) {
let done = false
return function () {
if (!done) {
done = true
return fn.apply(this, arguments)
}
}
}
let pay = once(function (money) {
console.log(`支付: ${money} RMB`)
})
pay(5)
pay(5)
pay(5)
pay(5)
常见的高阶函数有forEach map filter every some find findIndex reduce sort等等
好处可以帮我们隐藏掉实现的很多细节,只需要关注目标值x就能得到我们想要的结果y
闭包
子级作用域(内部函数)总是可以访问父级作用域(外部函数)中定义的变量。 父级作用域变量被子级作用域引用导致得不到释放的现象,只有等到子级作用域执行完后才被释放。
本质就是函数在执行栈中执行,执行完后(完成的标致值return 和 })从栈中移除,但是堆中保存的变量,因为被外部引用得不到释放,所以才有内部函数可以访问外部变量。
function makeSalary (base) {
return function (performance) {
return base + performance
}
}
函数柯里化 (Currying)
当判断一个结果多个参数,并且其中一个参数依赖于配置,后台返回等,使得函数相同输入得到不同输出
let mini = 18
function checkAge (age) {
return age >= mini
}
checkAge(19)// mini的值不确定,所以得到的结果也不确定。
函数柯里化,即当函数多个参数的时候可以传递一部分参数生成一个新的函数。调用新函数传递剩余的参数
function checkAge (min) {
return function (age) {
return age >= min
} }
// ES6 写法
let checkAge = min => (age => age >= min)
let checkAge18 = checkAge(18) let checkAge20 = checkAge(20)
checkAge18(24)
checkAge18(20)
lodash中的_.curry(func) 生成的形函数参数可以任意顺序传,结果不变
const _ = require('lodash') // 要柯里化的函数
function getSum (a, b, c) {
return a + b + c
}
// 柯里化后的函数
let curried = _.curry(getSum)
curried(1, 2, 3)
curried(1)(2)(3)
curried(1, 2)(3)
缓存函数memoize, 缓存上次结果。
function getArea (r) {
console.log(r)
return Math.PI * r * r
}
// 模拟 memoize 方法的实现
function memoize (f) {
let cache = {}
return function () {
let key = JSON.stringify(arguments)
cache[key] = cache[key] || f.apply(f, arguments)
return cache[key]
}
}
let getAreaWithMemory = memoize(getArea)
console.log(getAreaWithMemory(4))
console.log(getAreaWithMemory(4))
console.log(getAreaWithMemory(4))
函数组合compose
顾名思义就是需要经过多个函数执行后得到结果,我们可以把中间所有执行过程组合成一个新函数,相当于执行组合后的函数就得到了最终结果,默认执行顺序从右向左
y = f(g(h(x)))
即等价于
const fn=compose(f,g,h)
fn(x)
// 组合函数
function compose (f, g) {
return function (x) {
return f(g(h(x)))
} }
lodash 中组合函数 flow() 或者 flowRight(),他们都可以组合多个函数 flow() 是从左到右运行flowRight() 是从右到左运行,使用的更多一些