初探函數式編程

函數式編程是一種編程範式,它強調將計算視爲函數的運算,並避免改變狀態和可變數據。在 Web 前端開發中,函數式編程有着廣泛的應用,比如 React 組件編寫、Redux 狀態管理等。

純函數

函數式編程中的函數都是純函數,即函數輸入相同,輸出也必定相同,而且不會對外部狀態造成副作用。這樣的函數具有可測試性、可維護性和可複用性等優點。

下面是一個非純函數的例子:

let count = 0;
function add(num){
  count += num;
  return count;
}
console.log(add(1)); // 1
console.log(add(2)); // 3

上述函數 add 在每次調用時都會改變全局變量 count 的值,從而產生了副作用。如果需要實現累加器功能,可以使用閉包來封裝狀態:

function createAdder(){
  let count = 0;
  return function(num){
    count += num;
    return count;
  }
}
const add = createAdder();
console.log(add(1)); // 1
console.log(add(2)); // 3

上述代碼中,使用閉包將狀態 count 封裝到函數 createAdder 內部,實現了累加器的功能,並且不會污染全局變量。

高階函數

函數式編程中的高階函數指的是能夠接受函數作爲參數或返回函數的函數。高階函數有助於實現函數的組合和抽象,從而簡化代碼的邏輯。

下面是一個接受函數作爲參數的高階函數示例:

function filter(array, predicate){
  const result = [];
  for(let i = 0; i < array.length; i++){
    if(predicate(array[i])){
      result.push(array[i]);
    }
  }
  return result;
}
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = filter(numbers, n => n % 2 === 0);
console.log(evenNumbers); // [2, 4]

上述代碼中,filter 函數接受一個數組和一個謂詞函數作爲參數,然後通過遍歷數組並執行謂詞函數來篩選出符合條件的元素。這個例子展示了函數作爲參數的應用場景。

下面是一個返回函數的高階函數示例:

function multiplyBy(factor){
  return function(number){
    return number * factor;
  };
}
const double = multiplyBy(2);
console.log(double(3)); // 6

上述代碼中,multiplyBy 函數返回一個匿名函數,該函數實現了乘法運算。然後通過調用 multiplyBy(2) 來獲取實際的乘數,從而得到一個新的函數 double,該函數能夠將傳入的參數乘以 2。這個例子展示了函數作爲返回值的應用場景。

組合函數

函數式編程中,函數的組合指的是將多個函數串聯起來形成一個新的函數。組合函數有助於將邏輯分解爲多個小塊,提高代碼的可讀性和複用性。

下面是一個組合函數的示例:

function compose(...fns){
  return function(value){
    return fns.reduceRight((acc, fn) => {
      return fn(acc);
    }, value);
  };
}
function addOne(x){
  return x + 1;
}
function double(x){
  return x * 2;
}
const addOneAndDouble = compose(double, addOne);
console.log(addOneAndDouble(3)); // 8

上述代碼中,compose 函數接受任意個函數作爲參數,並返回一個新的函數,該函數能夠將所有參數函數從右至左依次執行,並將執行結果作爲下一個函數的參數。這個例子展示了函數組合在 Web 前端開發中的實際應用。

Curry 化

Curry 化是一種將多參數函數轉換爲單參數函數的技術。通過 Curry 化,我們可以更方便地對函數進行組合和抽象。

下面是一個 Curry 化的示例:

function curry(fn){
  return function curried(...args){
    if(args.length >= fn.length){
      return fn.apply(this, args);
    } else {
      return function(...rest){
        return curried.apply(this, args.concat(rest));
      };
    }
  };
}
function add(x, y, z){
  return x + y + z;
}
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 6

上述代碼中,curry 函數接受一個多參數函數 fn 作爲參數,並返回一個新的函數 curried,該函數能夠自動適配不同數量的參數。當傳入的參數數量達到原函數 fn 的參數個數時,curried 函數會立即調用原函數並返回結果;否則,curried 函數會返回一個新的函數,該函數繼續接受剩餘的參數,並遞歸調用自身。這個例子展示了 Curry 化在 Web 前端開發中的實際應用。

總結

函數式編程是一種強調函數運算、避免副作用和可變狀態的編程範式,它在 Web 前端開發中具有廣泛的應用。純函數、高階函數、組合函數和 Curry 化等技術都是函數式編程的核心概念,掌握這些技術能夠讓我們編寫更加清晰、簡潔和易於維護的代碼。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Ad5SjcWojIWAZxRsJ56_9g