魯斯前端布魯斯前端

文章中英模式

布魯斯前端JS面試題目 - 實作 Memoize 記憶化函數

學習如何實作 JavaScript 的記憶化(memoization)函數,提升函數執行效率,避免重複計算,掌握快取策略及其在前端開發中的應用。

影片縮圖

懶得看文章?那就來看影片吧

什麼是 Memoize 記憶化

記憶化(Memoization)是一種優化技術,通過儲存昂貴的函數調用結果,並在相同輸入再次發生時返回快取結果,來加速程式執行效率。它主要適用於函式型程式設計中的純函數(相同輸入總是產生相同輸出)。

記憶化的核心概念

  • 1. 快取結果:儲存函數調用的結果
  • 2. 快取命中:當相同參數再次呼叫時直接返回先前計算的結果
  • 3. 純函數:沒有副作用且輸出僅由輸入決定的函數,適合記憶化
  • 4. 效能優化:顯著減少重複計算的時間成本

實作基本的 Memoize 函數

下面是一個基本的 memoize 函數實作,能夠記憶任何純函數的結果:

function memoize(fn) {
  // 創建快取物件
  const cache = {};
  
  // 返回一個新函數
  return function(...args) {
    // 將參數轉換為字串作為鍵值
    const key = JSON.stringify(args);
    
    // 檢查快取中是否有相應結果
    if (key in cache) {
      console.log('從快取返回結果');
      return cache[key];
    }
    
    // 如果沒有快取,則調用原函數計算結果
    const result = fn.apply(this, args);
    
    // 將結果儲存到快取中
    cache[key] = result;
    
    return result;
  };
}

使用範例

// 计算斐波那契数列
function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

// 未记忆化的函数调用 (效能差)
console.time('未记忆化');
console.log(fibonacci(35)); // 这将花费较长时间
console.timeEnd('未记忆化');

// 记忆化版本
const memoizedFibonacci = memoize(function(n) {
  if (n <= 1) return n;
  return memoizedFibonacci(n - 1) + memoizedFibonacci(n - 2);
});

// 记忆化后的函数调用 (效能大幅提升)
console.time('记忆化');
console.log(memoizedFibonacci(35)); // 快速返回结果
console.timeEnd('记忆化');