首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在WeakMap中使用DOM节点作为密钥

在WeakMap中使用DOM节点作为密钥
EN

Stack Overflow用户
提问于 2018-08-07 22:24:56
回答 1查看 1.2K关注 0票数 2

在使用WeakMap时,我遇到了一个非常令人费解的场景:假设我有一个DOM节点,它包含我想要存储的一些数据,我使用元素/节点本身作为键,将任意数据作为值存储在WeakMap中。

在从WeakMap存储和检索条目之间,DOM节点发生了更改:比方说,它的id属性已经更新。我希望.get(<Node>)将返回undefined,因为节点已经发生了变异,但它仍然以某种方式返回它。

但是,当我销毁DOM树中的节点并重新呈现它时--即使不更改它的任何属性或属性--现在存储它时它被认为是WeakMap中的一个新元素。

我的问题是:为什么在WeakMap中更改DOM节点(它被用作存储任意数据的键)而不返回undefined?下面是一个概念证明示例,并给出了再现该行为的说明:

  1. 点击“存储元素”
  2. 单击“检索元素”以验证该元素确实存储在WeakMap
  3. 点击“变异元素”。元素应该更新其id属性。
  4. 单击“检索元素”:即使元素发生了变异,它仍然可以检索带有原始元素的值集。
  5. 单击“破坏并重新创建元素”。节点被从DOM中删除,它的outerHTML用于创建一个相同的外观元素。
  6. 单击“检索元素”:WeakMap正确地报告什么都找不到,因为我们使用一个全新的DOM节点作为键。

代码语言:javascript
复制
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');
});
代码语言:javascript
复制
<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>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-07 23:21:39

{} !== {}相同的原因是,两个对象具有相同的属性,或者如果它们被更改了,这并不重要,只是它们是否实际上是同一个对象--从技术上讲,是内存中相同的位置。如果要按属性和值比较对象,请使用深度相等的函数,如Lodash中的函数。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51736257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档