Skip to content

2026-10-07

/ 15 分鐘閱讀

/ Functional JavaScript First Steps

函數式程式設計入門:純函數為核心,用 JavaScript 跨出 Functional Programming 第一步 ​

課程定位:函數式程式設計的第一步 ​

這門課由 Anjana Vakil 主講,是 Functional JavaScript First Steps 的第二版。第一版在 2020 年推出,講師也笑說,函數式程式設計的原則從 1930 年代以來就沒什麼大改變,更別說是 2020 年之後。

這門課的定位是「打地基」。上完之後,學員應該能順利銜接 Frontend Masters 上整條函數式程式設計學習路徑,其他課程會更深入探討個別主題與相關工具。講師也強調,這門課只是「第一步」,不是全部的步驟。

課程全程使用 vanilla JavaScript,也就是我們熟悉的原生 JavaScript,目標是建立使用函數式原則寫程式所需的概念框架。這裡的「框架」指的是程式設計典範(paradigm)層面的思考方式,不是 React 那種意義上的框架。

課程教材與練習環境 ​

所有教材都放在 functional-first-steps.netlify.app。這個課程網站是用 StackBlitz 推出的 TutorialKit 打造的,整堂課的練習都直接在瀏覽器裡進行,不需要下載或安裝任何東西。

如果想在本機操作,網站主頁底部有說明,交代 repository 的位置與下載原始碼的方式。不過課堂上大家都直接在瀏覽器裡完成練習。

為什麼會想學函數式程式設計? ​

講師描述了一個常見的處境:成為開發者、慢慢站穩腳步之後,會發現程式越來越複雜,而這些複雜度越來越難掌控。這時自然會開始思考,有沒有更好的方式來組織程式與程式碼,讓自己更有生產力,寫出更好維護、更好預測、更好測試與除錯的程式。

講師認為,函數式程式設計是 JavaScript 開發者可以用來把程式寫得更好的工具之一。常會聽到一些函數式程式設計的術語,或「函數式才是真正的程式設計師的唯一做法」這種說法,這堂課不走這條路線,而是把函數式程式設計當成一種做法來探索。

課程會圍繞以下幾個問題展開:

  • 函數式程式設計是什麼?從高層次、整體的角度理解它的意義
  • 函數式的程式碼實際上長什麼樣子?
  • 寫函數式程式碼是什麼感覺?
  • 這在 JavaScript 裡做得到嗎?

最後一個問題,講師的答案是:當然可以。不需要另外學 Haskell 或 Clojure 這類一般被視為「函數式語言」的新語言,用 JavaScript 就能寫函數式程式。

課程地圖 ​

這門課會一路探索純函數、高階函數、一級函數(first-class functions)、遞迴、函數合成等聽起來很術語化的概念。

最重要的概念:純函數 ​

如果整堂課只能帶走一個觀念,講師希望是純函數(pure function)。課程會花很多時間在這個概念上,因為後面的技巧全都建立在純函數之上。

課程會談:

  • 什麼是純粹(purity),什麼不是
  • 在純函數式的程式裡,怎麼處理真實世界,讓程式真的能做有用的事
  • 為什麼處理真實世界對函數式程式設計來說是個挑戰

建立在純函數之上的技巧 ​

  • 遞迴(recursion):作為迭代(iteration)之外,重複執行某個操作的另一種做法。課程會實際寫幾個遞迴函數,挑戰一下大腦的思考方式
  • 高階函數(higher-order functions):JavaScript 裡本來就有很多常用的高階函數,寫過 JavaScript 的人很可能早就用過、甚至寫過高階函數,只是還不知道它叫這個名字
  • reduce、map、filter:講師稱它們是函數式程式設計師的好朋友。課程不會只依賴 JavaScript 內建的方法,而是自己重新實作一次,理解它們在函數式世界裡怎麼運作
  • 閉包(closure):一種特定類型的函數,能讓程式在執行過程中「記住」資料
  • 函數合成(function composition):把函數組合起來建立管線(pipeline),讓資料流經其中,整個程式基本上就變成一長串的資料轉換
  • 不可變資料(immutable data):說明不可變資料對函數式程式設計為什麼重要。JavaScript 原生並不支援函數式程式設計師偏好的那種不可變資料,所以課程也會介紹至少一個能補上這項功能的函式庫

為什麼要堅持純函數? ​

為什麼要忍受學一堆術語、甚至學新語言的痛苦?為什麼程式設計師要用這麼多不同的典範來折磨自己的大腦?講師的回答聚焦在純函數帶來的好處。

可預測、好測試、少驚喜 ​

如果一個函數除了輸入之外,不看外部世界的任何東西;除了回傳輸出之外,也不對外部世界做任何事,這個函數就會變得更可預測:

  • 更容易知道呼叫這個函數時會發生什麼事
  • 更容易測試
  • 在複雜的應用程式裡,比較不會遇到意外

講師舉了一個情境:程式依賴 name 這個變數維持原本的值,結果同事在不知情的情況下改掉了它,接著就開始納悶「為什麼會有這個 bug?」。這個 bug 的根源,在於函數讀取了輸入以外的外部變數。只要函數只依賴自己的輸入,別人改動外部變數就影響不到它。

讓所有函數都保持純粹,就是為了避免這類頭痛問題,目標是寫出更能容錯、更可預測、更好測試、更好除錯的程式。

讓開發者動得更快 ​

這些好處也會影響開發者的日常。在純函數式的世界裡,不需要去推敲「程式執行到這一行時,狀態應該是什麼」,也不用擔心這個狀態會不會被外面的天氣、現在幾點之類的因素影響。只需要知道這個函數只做一件事,而且可以驗證它是不是真的照預期運作。

不是為了顯得比較聰明 ​

講師也點出,有些人做函數式程式設計,是為了讓自己顯得聰明,並貶低其他程式設計師,宣稱函數式的做法是最好的、甚至是唯一的做法。講師明確表示不需要這些,不用函數式程式設計,一樣可以是很有生產力的程式設計師。

真正值得在意的,是它對開發者生活的具體好處:省下的頭痛,以及不必再為可變變數(mutable variables)這類東西焦慮而「多活好幾年」。這也是講師認為應該使用函數式 JavaScript 的理由。

為什麼用 JavaScript 學函數式程式設計? ​

講師自己的經驗 ​

講師大約十年前開始學 JavaScript,當時是 Python 開發者,習慣另一種物件導向語言,於是試著把那套原則對應到 JavaScript 上,結果遇到很多困惑:

  • JavaScript 有 prototype
  • this 關鍵字到處都是,還得背一堆它的規則

講師個人認為,在 JavaScript 裡做物件導向程式設計很快就會變得很棘手。改用函數式風格,或至少更偏函數式的風格之後,反而讓講師少擔心一點、多寫一點程式。

社群與生態系的支持 ​

很多人其實都在 JavaScript 裡做函數式程式設計,只是不一定會特別這樣標榜。因此有大量的社群資源、函式庫、工具與框架可以參考。

React 就是一個例子。React,至少在以 hook 為主的寫法下,深受函數式程式設計原則的啟發。React 應用程式的整體運作方式,包括響應式的更新,以及用宣告式的方式描述「我希望這個元素長這樣」,都非常符合函數式程式設計的精神。講師認為,函數式程式設計在過去十年左右對 Web 社群有相當大的影響。

能在周圍有其他人、有社群資源、有其他課程甚至整條學習路徑支持的環境下學習一種程式風格,是很大的優勢。這也是講師認為 JavaScript 適合作為函數式程式設計第一步的另一個理由。

打基礎的好地方 ​

就算之後一路深入範疇論(category theory)、monoid、functor、Haskell、Clojure,講師仍認為 JavaScript 是探索基礎的好地方:

  • 它具備我們需要的一切
  • 它就在瀏覽器裡
  • 有整個社群可以幫助我們學習

此文章是 FrontendMasters 上的 Functional JavaScript First Steps, v2 課程筆記

最後更新時間:

Buy Me A Coffee
0 %
MIT Licensed | Copyright © 2025-present Wen-Hsiu's Blog
Photo by Federica Galli on Unsplash