如今主流的两种方式,一种是 OOP (Object-oriented programming ) 面向对象编程,另外一种是 FP (Functional Programming)。本文稍微普及一下 FP 这种方式。javascript
与其余编程范式相比,FP的主要区别在于声明性方法(FP)与命令式方法。在咱们深刻了解正式定义以前,让咱们经过查看示例来探索差别。java
// 数组每一个元素乘三
const triple = (arr) => {
let results = []
for (let i = 0; i < arr.length; i++){
results.push(arr[i] * 3)
}
return results
}
// 数组求和
const sum = (arr) => {
let result = 0
for (let i = 0; i < arr.length; i++){
result += arr[i]
}
return result
}
复制代码
// 第一个例子
const triple =(arr)=> arr.map((currentItem)=> currentItem * 3)
//第二个例子
const sum =(arr)=> arr.redeuce((prev,current)=> prev + current,0)
复制代码
所谓"第一等公民"(first class),指的是函数与其余数据类型同样,处于平等地位,能够赋值给其余变量,也能够做为参数,传入另外一个函数,或者做为别的函数的返回值。react
// 好比咱们要先请求然数据而后渲染模板,可能会这么写
const render = (json) => {}
httpGet('/post/2', json => render(json))
复制代码
若是这个时候咱们除了拿数据还要拿 error 错误信息怎么办,你可能会想再加个参数编程
const render = (json, err) => {}
httpGet('/post/2', (json, err) => render(json, err))
复制代码
可是之后若是可还有其余参数怎么办??若是用一等公民的写法这样json
const render = (json, err) => {}
httpGet('/post/2', render)
复制代码
纯的意思是引用透明没有任何反作用 更多概念性的东西能够参考阮一峰大大的入门教程数组
// 不纯的
const minimum = 21
const checkAge = age => {
return age >= minimum
}
// 纯的
const checkAge = age => {
const minimum = 21
return age >= minimum
}
复制代码
再看下引用类型:闭包
const data = [1, 2, 3]
const a = data.slice(0, 1)
// [1]
const b = data.slice(0, 1)
// [1]
const c = data.slice(0, 1)
// 此处是为了对比因此用了const,正常确定会报错的
// [1]
const a = data.splice(0, 1)
// [1]
const b = data.splice(0, 1)
// [2]
const c = data.splice(0, 1)
复制代码
函数柯⾥里里化就是只传递给函数⼀一部分参数来调⽤用它,让它返回⼀一个函数去处 理理剩下的参数函数式编程
举个例子函数
function add (x, y) {
return x + y
}
function add (x) {
return function (y) {
return x + y }
}
const add = x => y => x + y
// add(2,3) 等价于 add(2)(3)
//舒服了
复制代码
这里咱们定义了一个 add 函数,它接受一个参数并返回一个新的函数。调用 add 以后,返回的函数就经过闭包的方式记住了 add 的第一个参数。一次性地调用它实在是有点繁琐,好在咱们可使用三方函数式编程库一个特殊的 curry 帮助函数使这类函数的定义和调用更加容易,后面我会把函数式编程库不错的列出来post
吃我个🌰
const data = [1, 2, 3]
const head = arr => arr[0]
const reverse = arr =>
arr.reduce((acc, item) => [item].concat(acc), [])
const last = compose(
head,
reverse
)
last(data) // 3
复制代码
这里只是举个例子取数组最后的一项,真正写起来不会这么麻烦那么我接下来举个你们用的比较多对象判空的例子
const user = {
name: 'cai',
address: {
city: 'hangzhou'
}
}
const city =
user &&
user.address &&
user.address.city
// 或者这样
const city = !user
? undefined
: !user.address
? undefined
: user.address.city
复制代码
用了函数式之后
const prop = key => obj => (obj === undefined || obj === null)
? null
: obj[key]
const getUserCity = compose(
prop('city'),
prop('address')
)
getUserCity(user) // hangzhou
复制代码
用对象的形式
class Maybe {
constructor(val) {
this. __val = val
}
static of(val) {
return new Maybe(val)
}
isNothing() {
return (this. __val === null || this. __val === undefined)
}
map(f) {
return (
this.isNothing()
? new Maybe(null)
: new Maybe(f(this. __val))
) }
}
/* 调用 */
// props :: s -> {s: a} -> a
const prop = key => obj => obj[key]
Maybe
.of(user)
.map(prop('address'))
.map(prop('city'))
// Maybe { __val: 'hangzhou' }
复制代码
用过 react 童鞋值到 react 有 hoc (高阶组件)的概念 其实也是把组件当成参数的形式传进来返回一个新的组件这点是共通的
我的理解系的很差望指证