關於 JavaScript Memoization

1.2k 詞

什麼是 JavaScript 記憶函式?

JavaScript 記憶函式(也稱為閉包)是一種函式,可以記住並訪問其創建時所在的作用域中的變量。這意味著,即使該函式在其創建的作用域之外被調用,它仍然可以訪問並修改該作用域中的變量。

以下是一個簡單的 JavaScript 記憶函式的範例:

1
2
3
4
5
6
const Fibonacci = (n, memo = {}) => {
if (n in memo) return memo[n];
if (n <= 2) return 1;
memo[n] = Fibonacci(n-1, memo) + Fibonacci(n-2, memo);
return memo[n];
}

費波那契數列是一個經典的數學問題,它是一個遞迴定義的數列,其中每個數字都是前兩個數字的和。費波那契數列的前幾個數字通常是 0、1、1、2、3、5、8,依此類推。在沒有記憶化的情況下,我們可以使用遞迴方式來計算費波那契數列。一個簡單的遞迴函式可能看起來像這樣:

1
2
3
4
5
const Fibonacci = n => {
if (n <= 1) return n;

return Fibonacci(n-1) + Fibonacci(n-2);
}

這段代碼的問題在於,每次計算 Fibonacci(n) 都會對 Fibonacci(n-1) 和 Fibonacci(n-2) 進行遞迴調用。這導致了大量的重複計算,尤其是在較大的 n 值下。沒有儲存先前計算結果的機制,每次遞迴調用都需要重新計算,導致了指數級的時間複雜度,效率極低

使用記憶函式(也稱為快取)是解決這個問題的一種方法。它使用了一個 memo 對象來存儲先前計算過的結果,以避免重複計算。這樣,當我們需要計算 Fibonacci(n) 時,如果之前已經計算過,就可以直接從 memo 對象中獲取結果,而不需要重新計算。

這樣一來,計算 Fibonacci 數列的效率大大提高,因為我們避免了對相同值的重複計算。使用記憶函式,時間複雜度可以降低到線性,而不是指數級的增長,這在處理大型輸入時特別重要

重點整理

  • JavaScript 記憶函式允許創建私有變量,這些變量僅在函式內部可訪問,而外部代碼無法直接訪問或修改它們。
  • 記憶函式可用於模擬私有成員變量,從而實現信息隱藏和封裝。
  • 透過閉包,可以創建具有狀態的函式,這意味著它們可以保持狀態並在多次調用之間共享數據。

優點

  1. 封裝性:記憶函式提供了一種封裝變量的方式,從而實現了信息隱藏和封裝。
  2. 狀態保持:記憶函式可以維護自己的內部狀態,從而允許在多次調用之間共享數據。
  3. 模組化:通過將相關邏輯封裝在一個函式中,可以更容易地創建模組化的程式碼。

缺點

  1. 內存消耗:記憶函式中的變量會一直存在於內存中,即使它們在作用域之外不再被使用,這可能導致內存消耗過大。
  2. 閉包理解難度:閉包和記憶函式的概念對於初學者來說可能有些難以理解,需要一定的學習成本。
留言