函數式編程

函數式編程又是一個平時在工作時經常聽到但是從來沒有接觸過並且會被搞的一頭霧水的東西。所以博主打算一探究竟這個函數式編程究竟是何物?

函數式編程

你能說出對javaScript工程師比較重要的兩種編程範式嗎?

什麼是函數式編程?

函數式編程和麵向對象各有什麼優點和不足呢?

你瞭解閉包嗎?你經常在那些地方使用?閉包和柯里化有什麼關係?

如果我們想封裝一個像underscorede的防抖的函數該怎麼實現?

你怎麼理解函子的概念?Monad函子又有什麼作用?

什麼是函數式編程

通常我們比較熟悉面向對象編程(Object-oriented programming,OOP),那麼函數式編程(functional programming,FP)有何不同?

面向對象編程是以數據為核心,對象則指的是類的實例。它將對象作為程序的基本單元,將程序和數據封裝其中,可以看作一種在程序中包含各種獨立而又互相調用的對象的思想。面向對象編程由於其有繼承、封裝、多態的特性,使得其具有高內聚低耦合、已擴展、成本低等優點。但是會造成數據的不確定性,在運行效率上也不如面向過程編程。

函數式編程是一種編程範型,面向過程的編程,它將電腦運算視為數學上的函數計算,並且避免使用程序狀態以及易變對象。簡單說,函數式編程所有的數據都是不可變的,所以安全性和穩定性上更盛一籌。函數式編程廣泛運用於科學研究中,因為在科研中對於代碼的工程化要求比較低,寫起來更加簡單。但是由於數據不可變在運行中一直存在,所以內存資源佔用很大。同時由於先天性的設計,性能也不樂觀。

純函數

前面聊到了函數式編程是一個面向過程的編程,舉個例子:a*3+5,通過函數式編程思想,a需要執行m和n操作,m和n首先合成l操作,然後a直接執行l操作,輸出。那麼m和n怎麼能完成合成操作呢?任意的m和n都能合成嗎?也許你已經開始產生疑問,那麼這裡就引入了純函數的概念。

純函數:一個函數如果輸入參數確定,輸出結果唯一不變,那麼該函數就是純函數。它無狀態,沒有副作用也無關時序問題,所依賴的函數也不會被受影響。

函數式編程

現在有這麼一種情況:

function move(func,a,b){

func(a,b)

}

move(delete,a,b)

如果delete函數會清楚a、b的數據,那move還算純函數嗎?答案是不算。那怎麼樣可以使move變成純函數?這裡就引入了柯里化操作,它是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,並且返回接受餘下的參數且返回結果的新函數的技術。

柯里化後的函數:

function move(func){

return function(a,b){

func(a,b)

}

}

move(delete,a,b)

這樣,無論func輸入什麼輸出的都是確定不變的函數,並且也沒有副作用,無關時序,所以現在該函數就是純函數了。

高階函數

在函數式編程中也經常涉及到高階函數的運用,先看定義:函數當參數,把傳入的函數做一個封裝,然後返回這個封裝函數,達到更高程度的抽象。比如我們經常使用的 map/reduce、filter等函數方法都是高階函數。再比如我們在滾動優化中涉及到的節流函數:

函數式編程

博客地址:https://252860883.github.io/


分享到:


相關文章: