《JS函數式編程指南》使用
JavaScript
講述了函數式編程的基本思想,函數式編程有不少優勢,好比簡潔,消除"反作用"等等。同時它是來源數學理論,能夠達到更高的抽象度。
函數式編程
也叫面向函數編程
,是編程範式的一種,它其實出現得很早,理論基礎起源於上個世紀30年代數學界的lambda
演算,屬於範疇論
,最先運用這一思想的編程語言是上世紀50年代的Lisp
語言,這門語言在黑客圈極具傳奇色彩。javascript
另外一種更爲你們知道的編程範式就是大名鼎鼎的面向對象編程
(固然,面向「對象」編程,是程序猿的夢想之一)。十年以前,咱們接觸到的編程教材、技術文章,講述的幾乎都是面向對象編程,編程不使用接口、類、繼承
,都很差意思說本身會編程。java
函數式編程思想近幾年愈來愈爲你們接受和推崇,兩大主流語言相繼增長了支持函數式編程的特性:程序員
Java8
新增了Lambda
表達式,同時增長了相關應用場景的支持,如Stream
流式處理;面試
JavaScript
也在ES6
增長了Lambda
表達式,也增長了相關應用場景的支持,如Array
的map, fliter, reduce
操做。同時,JavaScript
的三大框架之一React,今年新增了Hooks特性,支持有狀態函數組件,從而徹底能夠替代類組件。數據庫
從大的趨勢來看,各大主流語言逐漸趨於支持多種範式,如JavaScript同時也增長了面向對象的特性:類和繼承。編程
這是函數式編程一個基本條件,這裏並非說函數有什麼優先權,而是:函數和其它數據類型同樣,能夠賦值給變量、能夠做爲參數傳遞、能夠做爲返回值等等。後端
根據上面的特色,咱們還能夠引伸出來一些概念:設計模式
這些JS開發者都很熟悉,也會常常用到,等後面再回過頭看看這些特性在函數式編程裏面有什麼使用場景。數組
代碼示例:網絡
// 嵌套函數,返回函數 function regexCheck(reg) { return function(str) { return reg.test(str) } } // 高階函數 regexCheck(/^(130|131)\d{8}$/)('13012341234')
表達式的特色是:它是一個單純的運算過程,完成後老是會有運算結果。最多見的表達式就是運算表達式,好比:
const a = 10 const b = a * 10 + 10
函數式編程裏的表達式,其實就是把函數看成普通變量來使用:
// 參數函數,返回函數 function ifNot(func) { return function(x) { return !func(x) } } // 函數組合 const isHtmlTag = regexCheck(/<\/?\S+>/) ;['hello world', '<script>alert(1)</script>'].filter(ifNot(isHtmlTag))
把函數看成變量同樣來運算,代碼能夠變得很簡潔靈活(後續還會接觸更多的)。
這裏的"反作用"就是Side Effect
,指的就是:函數運行過程當中,產生了運算之外的其餘結果,好比:修改了全局變量、向數據庫寫入了數據、發起了網絡請求等等。
函數式編程爲何要消除「反作用」,經驗豐富的程序員必定知道,系統複雜性和Bug不少時候就是因"反作用"而起:
固然,咱們也不能徹底避免反作用,咱們要作的是控制它,狀態管理器Redux
中就有effects
概念,React Hooks
裏面也有effect hook
,目的都是隔離「反作用」。
消除"反作用"有一個常見的方案:不改變狀態,即函數調用返回新的值,如:
const serials = ['10', '20', '30'] // 下面的運算不會改變前面的變量 const serialsOpts = serials.concat(['40', '50']).join('/')
引用透明其實就是前面特性的衍生特性,說的就是:使用相同的參數調用函數,每次都會獲得相同的結果。 咱們徹底能夠用結果代替這個函數表達式,因此叫引用透明。
當一個函數不依賴外部變量和狀態時,它就能夠知足引用透明,這樣的函數咱們也叫它純函數。
它的好處不少:
函數編程起源於數學的範疇論,理論至關抽象,我仍是個初學者,本篇簡單介紹了函數式編程的歷史和現狀,講述了函數式編程的基本特色。後續我還會繼續學習和記錄函數式編程的相關理論、常見設計模式和它們的應用。
我的讀書公衆號,歡迎交流!