前端面试资料之大厂真题篇(三)

javascript中如何实现函数缓存?函数缓存有哪些应用场景?

资料来源:rss1.cn

函数缓存(也称为函数记忆化)是一种优化技术,通过存储函数的输入和对应的输出,避免对相同输入进行重复计算。这样可以提高性能,尤其是在函数计算复杂或调用频繁的情况下。

实现函数缓存

我们可以通过使用闭包和对象来实现一个简单的函数缓存。

示例:实现一个简单的函数缓存

function memoize(fn) {
  const cache = {}; // 存储函数输入和对应的输出

  return function(...args) {
    const key = JSON.stringify(args); // 使用输入参数作为缓存的键
    if (cache[key]) {
      console.log('Fetching from cache:', key);
      return cache[key];
    } else {
      console.log('Calculating result:', key);
      const result = fn(...args); // 计算结果
      cache[key] = result; // 存储结果
      return result;
    }
  };
}

// 示例函数:计算阶乘
function factorial(n) {
  if (n === 0 || n === 1) return 1;
  return n * factorial(n - 1);
}

const memoizedFactorial = memoize(factorial);

console.log(memoizedFactorial(5)); // Calculating result: [5]
console.log(memoizedFactorial(5)); // Fetching from cache: [5]
console.log(memoizedFactorial(6)); // Calculating result: [6]
console.log(memoizedFactorial(6)); // Fetching from cache: [6]

解释

  1. memoize 函数

    • memoize 是一个高阶函数,接受一个函数 fn 作为参数,并返回一个新的函数。
    • 内部维护一个 cache 对象,用于存储函数输入参数和对应的计算结果。
  2. 闭包

    • cache 对象在 memoize 函数内部定义,并且在返回的新函数中被引用,因此可以记住函数调用之间的状态。
  3. 缓存机制

    • 使用输入参数数组的字符串表示作为缓存的键(key)。
    • 如果缓存中存在对应的键,直接返回缓存的值。
    • 如果缓存中不存在对应的键,计算结果并存储在缓存中。

应用场景

函数缓存在很多场景中都非常有用,特别是那些具有高计算成本的场景:

  1. 计算密集型函数

    • 如数学计算(例如:阶乘、斐波那契数列等),这些函数在相同输入情况下重复计算会浪费大量资源。
  2. API调用

    • 缓存API调用结果,可以减少对服务器的请求,提升性能。
  3. 数据转换和格式化

    • 如复杂的字符串操作、日期格式化等。
  4. 前端性能优化

    • 在React等框架中,缓存组件的渲染结果,避免不必要的重新渲染。

示例:缓存API调用

async function fetchData(url) {
  const response = await fetch(url);
  const data = await response.json();
  return data;
}

const memoizedFetchData = memoize(fetchData);

memoizedFetchData('https://api.example.com/data').then(data => {
  console.log(data); // 第一次调用,会进行实际的API请求
});

memoizedFetchData('https://api.example.com/data').then(data => {
  console.log(data); // 第二次调用,会返回缓存的结果
});

注意事项

  1. 缓存大小和失效策略

    • 需要考虑缓存的大小以及何时清除缓存(例如:使用LRU缓存策略)。
  2. 引用类型的比较

    • 上述例子使用 JSON.stringify 将参数转换为字符串作为键,这对于简单的数据结构有效,但对于复杂的数据结构可能效率不高。可以考虑使用深比较或自定义序列化函数。
  3. 函数副作用

    • 只有纯函数(相同输入总是返回相同输出,没有副作用)适合缓存。如果函数有副作用(例如:修改全局状态或依赖外部状态),则不适合使用缓存。
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值