pure function


Posted by TempuraEngineer on 2022-10-05

目錄


pure function是甚麼

pure function是functional programming的一個概念,它需要滿足2個條件

  1. 樣的輸入會得到樣的輸出(Given the same input, always returns the same output.)
    這意味著pure function裡呼叫的function也必須是pure function

  2. 產生副作用(Produces no side effects.)

    • 不影響這個function scope之外的其他變數(Mutating data)
    • 不操作、修改DOM(DOM Query/Manipulation)
    • 不發HTTP request、不操作資料庫
    • 不取得現在時間(new Date())、使用Math.random()、不用計時器(setTimeout、setIntrval)

pure function的優點則如下

  • 複用性
    每個pure function都「簡單」又「蠢」(Keep It Simple, Stupid)
    因為它們都只做些簡單的事,所以有利於重複使用、組裝、重構

  • 可測試性
    同輸入同輸出、無外部dependency的特性,讓pure function具備高可預測性,所以會比較好測試

  • 利於debug

(2024/2/5更新)

不過實際上有些會產生side effect的動作是不可免的,所以真正在開發專案時,完全pure的程式碼是不可能存在的

但是仍然可以用monad的方式把impure的地方隔離(之後寫在其他篇)


範例

  1. 同輸入異輸出(共用狀態)

    依賴外部狀態的函式不是pure function

    A pure function must not rely on any external mutable state

    let money = 1000;
    
    function addComma(){
        const regex = /\B(?=(\d{3})+(?!\d))/g;
    
        if(money === undefined) return '0'; // 依賴外部狀態
    
        return money.toString().replace(regex, ',');
    }
    
    function addMoney(num){
      money += num; // 異動外部狀態
    }
    
    addComma(); // 1,000
    
    addMoney(500);
    addComma(); // 1,500
    

    改寫後

    function addComma(money){
        const regex = /\B(?=(\d{3})+(?!\d))/g;
    
        if(money === undefined) return '0';
    
        return money.toString().replace(regex, ',');
    }
    
    addComma(1000); // 1,000
    addComma(1000); // 1,000
    
  2. 異動了其他變數

    const person = {
      name:'Bob',
      job:'teacher'
    };
    
    function changeProfile(data, key, value){
      data[key] = value; // 直接更動屬性值會影響物件
    }; 
    
    changeProfile(person, 'age', 33);
    
    console.log(person); // {name: 'Bob', job: 'teacher', age:33}
    

    改寫一下

    const person = {
      name:'Bob',
      job:'teacher'
    };
    
    function changeProfile(data, key, value){
      const res = JSON.parse(JSON.stringify(data)); // 深拷貝才能完全避免副作用
    
      res[key] = value;
    
      return res; // 使用return 避免直接為物件加上屬性或更新屬性的值
    }; 
    
    changeProfile(person, 'age', 33);
    
    console.log(person); // {name: 'Bob', job: 'teacher'}
    


參考資料

Master the JavaScript Interview: What is a Pure Function?
What Is a Pure Function in JavaScript?
純粹的好,Pure Function 知道
第 3 章:Pure Function
初探Functional Programming:徹底改變程式思維 - 基礎概念篇


#pure function #Functional Programming







Related Posts

序列化操作(JSONObject)

序列化操作(JSONObject)

[ JS101] JavaScript 內建函式

[ JS101] JavaScript 內建函式

[ 筆記 ] JavaScript - 測試 Jest - TDD

[ 筆記 ] JavaScript - 測試 Jest - TDD


Comments