如今主流的兩種方式,一種是 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 (高階組件)的概念 其實也是把組件當成參數的形式傳進來返回一個新的組件這點是共通的
我的理解系的很差望指證