JS每日一題:函數式編程中代碼組合(compose)如何理解?

20190315期

函數式編程中代碼組合(compose)如何理解?react

定義: 顧名思義,在函數式編程中,Compose就是將幾個有特色的函數拼湊在一塊兒, 讓它們結合, 產生一個嶄新的函數

代碼理解:git

// 一個將小寫轉大寫的函數
let toUpperCase = (x) => x.toUpperCase();

// 一個在字符後加!的函數
let exclaim = (x) => x + '!';

// 將兩個函數組合起來, 這裏假設咱們實現了compose
let shout = compose(toUpperCase,exclaim);

shout('js每日一題') // JS每日一題 !, 顯示結果裏上面兩個函數的特色都應用上了

pointfree

代碼組合中有一個重要的概念pointfree(永遠不要說出你的數據), 它的意思是指函數無須說起將要操做的數據是什麼樣的github

有點晦澀,咱們仍是上代碼理解一下編程

// 咱們有一個將字符轉換成大寫而且將其空格轉換爲'-'的函數
// 細節的同窗應該發現這個函數暴露了一個word形參
// 根據pointfree定義,此函數非pointfree模式
let snakeCase = (word) => word.toUpperCase().replace(/\s+/ig,'-');

// 下面這個函數與上面的功能一致,但咱們能夠觀察到其沒有數據暴露,因此其爲pointfree模式
let snakeCase = compose(replace(/\s+/ig,'-'),toUpperCase)

說了這麼多,他能幹什麼呢 ? 它可以幫助咱們減小沒必要要的命名,讓代碼保持簡潔和通用redux

compose實現

上面咱們都是假設已經存在compose方法, 接下來咱們來爲其實現數組

首先分析其特性promise

  • 兩個函數都有一個共同的參數
  • 函數的執行順序從右至左
  • 前面函數執行的結果交由後面的函數處理

根據上面的示例及咱們分析的特性來實現一個最簡版的函數式編程

// 這樣子其實就能知足咱們上面示例的要求了
const compose = function(f, g) {
  return function(x) {
    return f(g(x));
  };
};

結束了嗎? 並無,咱們能夠看到上面的compose示例都只是傳入了兩個函數,由於咱們的簡版compose實現也只支持兩個函數,那麼若是咱們想要支持一條很長很長的管道的時候,顯然上面的compose就不夠用了, 接着咱們來看優秀的開源庫redux的compose實現函數

// 摘自 https://github.com/reactjs/redux/blob/master/src/compose.js
export default function compose(...funcs) {
  // 沒有傳入函數運行直接返回參數
  if (funcs.length === 0) {
    return arg => arg
  }
  // 只傳入一個函數,就返回其自己
  if (funcs.length === 1) {
    return funcs[0]
  }
  
  // 核心代碼其實就是一句reduce, reduce特性就是按順序執行,而且將結果傳遞給下一次執行, 這裏多說一句, reduce順序執行多個相依賴的promise也很好用
  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}

總結

  • 將多個單特性的函數組合到一塊兒的函數
  • 多個函數服務一組數據(共同參數)
  • 沒必要說出數據(pointfree)
  • 函數從右至左順序執行,結果作爲下一個函數的參數

關於JS每日一題

JS每日一題能夠當作是一個語音答題社區
天天利用碎片時間採用60秒內的語音形式來完成當天的考題
羣主在第二天0點推送當天的參考答案學習

  • 注 毫不僅限於完成當天任務,更可能是查漏補缺,學習羣內其它同窗優秀的答題思路

點擊加入答題

相關文章
相關標籤/搜索