You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Memoization生成不重复随机数?解决HTML元素随机Key缓存问题

问题分析与解决方案

现有代码的问题

第一个函数的问题

你写的generateRandomKey函数,参数cache = []的默认值是每次调用函数时才会创建新数组——也就是说,如果你每次调用都不传cache参数(比如直接调用generateRandomKey()),那每次都会生成空数组,缓存自然留不住。就算手动传cache,每次调用还得自己管理这个数组,非常麻烦。

第二个memoization代码的问题

这段代码有两个核心问题:

  1. 语法错误:if (cache.includes(key)缺少闭合的),直接运行会报错。
  2. 逻辑错误:memoizedRandomKey(cache)返回的是一个新函数,而不是生成的key,调用时根本拿不到结果;而且闭包结构完全搞错了,没能真正把缓存封装在内部复用。

推荐方案:用闭包封装缓存

不用全局变量也能保住缓存,闭包是最合适的方案。把缓存放在外层函数的作用域里,内层函数负责生成key,这样缓存只会初始化一次,每次调用内层函数都会复用同一个缓存:

function createKeyGenerator() {
  const cache = [];
  // 单独抽出生成key的逻辑,方便后续修改
  function generateRawKey() {
    // 改用更高精度的随机字符串,避免很快耗尽所有可能值
    return Math.random().toString(36).slice(2, 10);
  }

  return function() {
    let key;
    do {
      key = generateRawKey();
    } while (cache.includes(key));
    cache.push(key);
    return key;
  };
}

// 使用方式:先创建生成器,之后每次调用就能拿到不重复的key
const getUniqueKey = createKeyGenerator();
console.log(getUniqueKey()); // 示例输出:"x7k2b9z4"
console.log(getUniqueKey()); // 另一个不重复的key

这个方案的优势:

  • 缓存cache被封装在闭包里,不会污染全局作用域
  • 每次调用getUniqueKey()都会复用同一个缓存,不会丢失
  • 生成key的逻辑可以单独修改,扩展性更好

你原有逻辑的漏洞

  1. key取值范围极小:Math.random().toFixed(2)生成的是0.00到1.00之间的两位小数,总共只有101个可能的值。一旦生成过101次,后续调用会无限递归(所有可能的key都在缓存里了),直接导致栈溢出。
  2. 默认参数逻辑错误:第一个函数的cache = []默认值,每次调用都会新建数组,完全起不到缓存作用。
  3. memoization结构错误:没有正确利用闭包保存缓存,反而每次调用都返回新函数,根本无法复用缓存。

额外建议

如果是给HTML元素用key,还有更简单的替代方案:

  • 自增整数:维护一个计数器,每次调用加1,绝对不会重复,性能比随机值更好(不用检查缓存)
  • UUID:用crypto.randomUUID()(现代浏览器支持),直接生成唯一的UUID,不需要缓存,因为UUID重复的概率可以忽略不计

自增整数的实现示例:

function createIncrementalKeyGenerator(start = 0) {
  let counter = start;
  return function() {
    return counter++;
  };
}

const getKey = createIncrementalKeyGenerator();
console.log(getKey()); // 0
console.log(getKey()); // 1

内容的提问来源于stack exchange,提问作者ElMoscaviador

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:41:42