理解概念
函數(shù)式編程是一種編程范式,例如面向?qū)ο缶幊?br>
函數(shù)式編程的主要思想是:把事物之間的聯(lián)系抽象到程序中,對運算過程進行抽象
指的是數(shù)學中函數(shù)的映射關系 相同的輸入始終要有相同的輸出
//非函數(shù)式
let a = 1
let b = 2
let c = a+b
alert(c)
// 函數(shù)式
let sum = (a ,b) => a + b
alert(sum(1, 3))
高階函數(shù)
- 把函數(shù)作為參數(shù)帐姻,傳遞給另一個函數(shù)
- 可以把函數(shù)作為另一個函數(shù)的返回結(jié)果
高階函數(shù) 可以幫助我們屏蔽實現(xiàn)的細節(jié)忘伞,只需要關注我們的目標
// 過濾器
function filter(arr, func) {
let copyArray = []
for (let i = 0; i < arr.length; i++) {
const element = arr[i];
if (func(element)) {
copyArray.push(element)
}
}
return copyArray
}
const arr = [2, 5, 1, 6, 10, 7]
// 函數(shù)作為參數(shù)
let res = filter(arr, function (item) {
return item % 2 === 0 // 返回偶數(shù)
})
console.log(res) // 2,6微峰,10
// 只執(zhí)行一次
function once(func) {
let done = false
return function () {
if (!done) {
done = true
return func.apply(this, arguments)
}
}
}
// 函數(shù)作為另一個函數(shù)的返回結(jié)果
const payMoney = once(function (num) {
console.log(`支付成功${num}元`)
})
payMoney(1) // 支付成功1元
payMoney(2)
payMoney(3)
payMoney(4)
payMoney(5)
閉包
上面寫的once()函數(shù)其實就是一個閉包舷丹。
閉包的本質(zhì):函數(shù)執(zhí)行的時候會放到一個執(zhí)行棧上,當函數(shù)執(zhí)行完畢會從執(zhí)行棧上移除蜓肆,但是堆上的作用域成員因為被外部引用不能釋放颜凯,內(nèi)部函數(shù)依然可以訪問外部函數(shù)成員(延長局部變量的生命周期)
柯里化
當一個函數(shù)有多個參數(shù)的時候,先傳遞一部分調(diào)用它(這部分參數(shù)以后永遠不變)
然后返回一個新的函數(shù) 接收剩余的參數(shù)仗扬,返回結(jié)果
const _ = require('lodash')
// 正則匹配
const match = _.curry((reg, str) => str.match(reg)
)
// 查找空格
const havaSpace = match(/\s+/g)
// 查找數(shù)字
const havaNumber = match(/\d+/g)
console.log(havaSpace('hello feir'))
console.log(havaNumber('hello feir'))
// 過濾數(shù)組
const filter = _.curry((func, array) => array.filter(func)
)
console.log(filter(havaSpace, ['feir hello', 'feir_hello']))
// 柯里化 只傳遞一個參數(shù)
const findSpace = filter(havaSpace) // 查找出有空格的元素
console.log(findSpace(['feir hello', 'feir_hello']))
//模擬一個curry
function curry(func) {
return function curridfn(...args) {
// args 實參 func.length 形參
if (args.length < func.length) {
return function () { //形成了一個閉包
return curridfn(...args.concat(Array.from(arguments)))
}
} else {
return func(...args)
}
}
}
const getSum = (a, b, c) => a + b + c
const currid = curry(getSum)
console.log(currid(1)(4, 5))
組合函數(shù)模擬
const reverse = arr => arr.reverse()
const first = arr => arr[0]
const toUpper = s => s.toUpperCase()
const compose = (...args) => value => args.reverse().reduce((acc, fn) => fn(acc), value)
const f = compose(toUpper, first, reverse)
console.log(f(['tom', 'cat', 'jesse']))
functor
// 函子
class Container {
static of(value) {
return new Container(value)
}
constructor(value) {
this._value = value // 私有屬性
}
map(fn) {
return new Container(fn(this._value))
}
}
let a = Container.of(5)
.map(x => x + 1)
.map(x => x * x)
console.log(a)