概念: 相同的輸入,永遠獲得相同的輸出,並且沒有任何可觀察的反作用
舉個例子🌰:javascript
let arr = [1, 2, 3]; arr.slice(0,3) //=> 1,2,3 arr.splice(0,3) // => 1,2,3
雖然兩個函數都返回了[1, 2, 3],可是splice的反作用是arr數組永久的發生了改變,在函數是編程中,咱們須要的結果是穩定的,而不是把數據弄得一團糟的函數,這不是咱們想要的 java
再舉個例子🌰:git
var minimum = 21; var checkAge = age => { return age > minimum } // 上面是一個不純的函數,下面是一個純的函數 var checkAge = age => { var minimum = 21; return age > minimum }
在第一個函數中,checkAge的結果取決於外部變量minimum的值,引入了外部的環境,從而增長了認知負荷數據庫
咱們來看看在概念中沒有任何可觀察的反作用有什麼?編程
概念:反作用是在計算結果的過程當中,系統狀態的一種變化,或者與外部世界進行的可觀察的交互
包含但不限於:segmentfault
固然,並非說要禁止使用一切反作用,若是函數是和外部事物打交道,那麼這一點就沒法保證了數組
函數的概念: 每個輸入值返回且只返回一個輸出值
函數就是數學上的函數,並且是函數式編程的所有,總能根據相同的輸入返回相同的輸出,總能保證返回同一個結果緩存
函數式編程的好處:dom
只傳遞給函數部分參數,讓它返回一個函數來處理剩下的參數
let sayHello = msg => { return name => { return msg + ', My name: ' + name } } sayHello('Hello')('毅翔')
加上一個場景來一個柯里化的例子: ide
初始化一個年齡,再加上一個age去判斷是否大於初始化這個年齡
let checkAge = initAge => { return age => { return age > initAge } } checkAge(22)(18) // fasle 判斷 18 是否大於
在lodash庫中使用curry
var _ = require('lodash') // 判斷age1 是否小於 age2 // 首先柯里化一個純函數 let judge = _.curry((age1, age2) => { return age1 < age2 }) console.log(judge(1)(2)) // 判斷數組arr中是否存在num let include = _.curry((arr, num) => { return arr.includes(num) }) console.log(include([1, 2, 3, 4])(2));
let compose = (f, g) => { return (x) => { return f(g(x)) } } let f = o => o.toUpperCase() let g = o => o + '!' compose(f, g)('asd')
我理解的函數式編程是一種思惟,是一種理想化的開發,瞭解函數式編程並不表明你必定會在項目中去使用,在JS開發中,可能會遇到dom操做,http請求,NodeJs中文件讀寫等等,會遇到不少反作用,參考某位做者,建議在代碼中尋找平衡,最大發揮函數式編程的做用,固然也許,你並不須要它
函數式編程GitBook
Noodles SegmentFault 技術週刊 Vol.16 - 淺入淺出 JavaScript 函數式編程