函數式編程探索(一) -《JS函數式編程指南》讀後感

《JS函數式編程指南》使用 JavaScript講述了函數式編程的基本思想,函數式編程有不少優勢,好比簡潔,消除"反作用"等等。同時它是來源數學理論,能夠達到更高的抽象度。

介紹

函數式編程也叫面向函數編程,是編程範式的一種,它其實出現得很早,理論基礎起源於上個世紀30年代數學界的lambda演算,屬於範疇論,最先運用這一思想的編程語言是上世紀50年代的Lisp語言,這門語言在黑客圈極具傳奇色彩。javascript

另外一種更爲你們知道的編程範式就是大名鼎鼎的面向對象編程(固然,面向「對象」編程,是程序猿的夢想之一)。十年以前,咱們接觸到的編程教材、技術文章,講述的幾乎都是面向對象編程,編程不使用接口、類、繼承,都很差意思說本身會編程。java

函數式編程思想近幾年愈來愈爲你們接受和推崇,兩大主流語言相繼增長了支持函數式編程的特性:程序員

Java8新增了Lambda表達式,同時增長了相關應用場景的支持,如Stream流式處理;面試

JavaScript也在ES6增長了Lambda表達式,也增長了相關應用場景的支持,如Arraymap, 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('/')

引用透明

引用透明其實就是前面特性的衍生特性,說的就是:使用相同的參數調用函數,每次都會獲得相同的結果。 咱們徹底能夠用結果代替這個函數表達式,因此叫引用透明。

當一個函數不依賴外部變量和狀態時,它就能夠知足引用透明,這樣的函數咱們也叫它純函數

它的好處不少:

  • 很容易的理解和推導程序。
  • 咱們還能夠很容易地構建測試程序,由於它的運算邏輯是單純、穩定的。
  • 能夠任意地並行執行。

總結

函數編程起源於數學的範疇論,理論至關抽象,我仍是個初學者,本篇簡單介紹了函數式編程的歷史和現狀,講述了函數式編程的基本特色。後續我還會繼續學習和記錄函數式編程的相關理論、常見設計模式和它們的應用。

歡迎交流

我的讀書公衆號,歡迎交流!
讀書三到-讀書,學習技術

相關文章
相關標籤/搜索