使用时
WeakMap
我遇到了一个非常令人困惑的场景:假设我有一个包含一些要存储的数据的dom节点,并将其存储在
弱映射
使用元素/节点本身作为键,使用任意数据作为值。
在存储和检索条目之间
弱映射
,DOM节点已更改:例如,
id
属性已更新。我希望
.get(<Node>)
会回来的
undefined
因为节点已经发生了变异,但是它仍然以某种方式返回它。
但是,当我销毁DOM树中的节点并在不更改其任何属性或属性的情况下重新呈现它时,它现在被认为是
弱映射
储存时。
我的问题是:为什么要在
弱映射
,不返回
未定义
?下面是一个概念证明示例,其中包含复制行为的说明:
-
点击“存储元素”
-
单击“检索元素”以验证元素是否确实存储在
弱映射
-
点击“突变元素”。元素应该具有
身份证件
属性已更新。
-
点击“检索元素”:即使元素已经变异,它仍然可以检索原始元素设置的值。
-
单击“销毁并重新创建元素”。节点将从DOM中移除,其
outerHTML
用于创建外观相同的元素。
-
点击“检索元素”:
弱映射
正确地报告找不到任何东西,因为我们使用一个全新的dom节点作为键。
const map = new WeakMap();
// Store element in WeakMap
document.getElementById('set').addEventListener('click', () => {
const el = document.querySelector('#content > div');
map.set(el, el.outerHTML);
console.log('Element stored in WeakMap');
});
// Retrieve element from WeakMap
document.getElementById('get').addEventListener('click', () => {
const el = document.querySelector('#content > div');
const elHTML = map.get(el);
if (elHTML)
console.log(`Element found in WeakMap, it's data: ${elHTML}`);
else
console.log('Element not found in Weakmap!');
});
// Mutate the DOM node, let's say by giving it a new unique ID
let n = 0;
document.getElementById('mutate').addEventListener('click', () => {
document.querySelector('#content > div').id = `test${n}`;
console.log(`Element ID updated to: "test${n}"`);
n++;
});
// Destroy and recreate element
document.getElementById('destroy_and_recreate').addEventListener('click', () => {
const target = document.querySelector('#content > div');
const targetHTML = target.outerHTML;
target.remove();
document.getElementById('content').innerHTML = targetHTML;
console.log('Element destroyed and recreated');
});
<section id="content">
<div id="test">Lorem ipsum dolor sit amet</div>
</section>
<hr />
<button type="button" id="set">Store element</button>
<button type="button" id="get">Retrieve element</button>
<hr />
<button type="button" id="mutate">Mutate element</button>
<button type="button" id="destroy_and_recreate">Destroy and recreate element</button>