将 HTML 节点作为键存储在*对象*中

dan*_*jah 3 javascript properties reference key object

与这个SO问题类似,我想使用HTML节点作为对象(而不是数组)中的键。

例子:

var _hotspots = {
                 [object HTMLDivElement] : { someProps:[1,2,3] },
                 [object HTMLDivElement] : { someProps:[1,2,3] }
                }
Run Code Online (Sandbox Code Playgroud)

所以我可能会实现这样的目标:

for( var a in _hotspots ){
    if(YAHOO.lang.hasOwnProperty(_hotspots, a)){
    alert('key nodeName: '+a.nodeName);
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,当我警告上面的“a”时,它警告说它实际上是一个[object HTMLDivElement],所以一切看起来都很好 - 但我无法访问“a”上的属性,例如nodeName。

我正在做的事情可能吗?这是错的吗?如果我应该能够访问对象的关键引用上的属性,请告诉我,我将编写一个示例页面。

干杯。

Cal*_*lor 6

现在可以使用MapSet对象来执行此操作,但如果您想存储键值对(例如常规对象),则 Map 更合适。

您仍然可以使用常规对象添加节点作为键,但问题是节点被转换为字符串,因为对象只能将键存储为字符串,这意味着该对象无法区分具有相同属性/结构的唯一节点。

之所以Map有效,是因为它的键可以是任何值,包括函数、对象或任何原语。

const divEl1 = document.querySelectorAll("div")[0];
const divEl2 = document.querySelectorAll("div")[1];

const obj = {};
const map = new Map();

obj[divEl1] = divEl1.getBoundingClientRect();
map.set(divEl1, divEl1.getBoundingClientRect());

console.log("Object: is divEl1? ", !!obj[divEl2]);
console.log("Map: is divEl1? ", map.has(divEl2));
console.log("Map: get divEl1 bounding properties", map.get(divEl1));
Run Code Online (Sandbox Code Playgroud)
<body>
  <div class="foo" data-some-id="1">I am a <span>div</span></div>
  <div class="foo" data-some-id="1">I am a <span>div</span></div>
</body>
Run Code Online (Sandbox Code Playgroud)

您还可以使用WeakMapWeakSet添加节点作为键。一旦元素从 DOM 中删除,使用Map/Set存储元素会带来潜在的内存问题,因为它们仍然保存在Map/中Set并且不会被垃圾回收。使用WeakMap/时WeakSet,如果不存在对存储在这些对象中的这些元素的其他引用,则这些元素将被垃圾收集。


ic3*_*3rg 5

JavaScript 对象的键始终是字符。您可以将 id 存储为键,然后在函数中检索该元素。

  • 如果指定非字符串作为属性名称,它会首先转换为字符串。因此,分配 DOM 元素就像分配“element.toString()”作为名称。 (2认同)