1. 程式人生 > >js函數式編程(1)-純函數

js函數式編程(1)-純函數

描述 都是 img isp 運行時 fun 是什麽 ade 結果

我將寫的第一個主題是js的函數式編程,這一系列都是mostly adequate guide這本書的讀書總結。原書在gitbook上,有中文版。由於原作者性格活潑,書中夾雜很多俚語,並且行文灑脫。中文譯版難免有時需要思量一番,既然讀了就寫出來,能方便別人最好,也請讀者指正。正文如下。

如果一個函數是純函數,那麽其不依賴外部環境,並且不產生副作用。

  • 1.不依賴外部環境,反例如下:
const a1 = 10;
const aFunc1 = () => {
  // 依賴外部變量
  return a1;
}

依賴外部環境的函數在運行時必須滿足環境條件,如上,aFunc1在a1創建之前運行,就出錯了。

  • 2.不產生副作用。所謂副作用,是一切與外部交互的作用,比如console.log,IO,網絡請求等。這些操作的結果是不可預計的,所以當包含副作用操作的函數執行後,結果是不可預計的。比如IO讀寫失敗,網絡出現問題,console.log通常沒什麽問題,但這仍然是外部的。舉個片面的例子,在react裏使用,就有可能因為打印某個在未來會被改變的狀態,導致組件不必要的被刷新。

  • 3.函數與外部的合法交互只能通過參數傳遞的方式。

那麽為什麽要用純函數,純函數和函數式編程有什麽關系?

函數式編程,本質上是數學,它是數學現有理論在編程上的實現,在數學上,一個定理成立通常要滿足一些數學條件,函數式編程也需要滿足條件,這個條件就是函數必須是純函數。

那麽這是什麽數學理論呢?

技術分享圖片

如上圖,可以用一個函數表達式描述,即y = f(x),這是一種一一對應關系,輸入x能得到唯一的結果y。也就是說x經過f的轉換變成y,這個過程是穩定的,確定的,以此類推,y也可以經過某種確定的轉換g,變成z,那麽就具有如下等式:

\[y = f(x) = 2x\]

\[z = g(y) = y + 1\]

\[z = g(f(x)) = w(x) = 2x + 1\]

也就是說x經過w轉換,可以變成z

技術分享圖片

某個狀態經過多個函數轉換成另一個狀態,那麽中間轉換過程可以結合成一個轉換,這大大的使問題簡化,這是函數式編程帶來的好處,而且只是一部分的好處,而這都基於純函數。

如何看待副作用?

當然,我們知道,很多時候無法避免使用副作用。就如發送消息,必須經過網絡。那是否函數式編程沒有實際運用價值呢?當然不是。所有事情都不應該極端的理解,函數式編程的種種定理必須以純函數作為根基,目的是寫出健壯的,聲明式的代碼。可以利用函數式編程中如curry,functor,monad等奇巧淫記,將副作用加以限制並降到最低限度,保證代碼的大部分是純的。

js函數式編程(1)-純函數