WeakMap 能不能用来缓存 DOM 元素的计算结果?
我在做一个动态表格,想用 WeakMap 缓存每个单元格的格式化结果,避免重复计算。但发现缓存好像没生效,是不是我用错了?
我试过这样写:
const cache = new WeakMap();
function formatCell(cell) {
if (cache.has(cell)) {
return cache.get(cell);
}
const result = expensiveFormat(cell.textContent);
cache.set(cell, result);
return result;
}
但每次调用 formatCell 都重新计算了,WeakMap 里的值似乎被清掉了。DOM 元素不是还在页面上吗?为啥缓存不住?
问题大概率出在作用域上。仔细检查一下你的
cache变量是不是每次都重新创建了。我见过太多人把const cache = new WeakMap()写在函数内部或者某个会重复执行的代码块里,那每次调用肯定都是空的 WeakMap 啊。正确的写法应该是把 cache 提到外面去:
还有个常见坑,如果你的表格是动态渲染的,比如用框架或者 innerHTML 重写了表格内容,那原来的 DOM 元素引用就失效了,WeakMap 里对应的缓存自然也被清理掉。这种情况用 WeakMap 反而是对的,因为它不会造成内存泄漏,只是你需要接受"重新计算一次"这个代价。
WP里面做复杂交互的时候也常遇到这问题,建议你在
cache.set那行加个console.log('设置缓存', cell),看看是不是调用次数比你预期的多,这样能快速定位是作用域问题还是 DOM 重建问题。