admin管理员组

文章数量:1289516

Similar to this SO question, I would like to use HTML nodes as keys in an object (not an array).

Example:

var _hotspots = {
                 [object HTMLDivElement] : { someProps:[1,2,3] },
                 [object HTMLDivElement] : { someProps:[1,2,3] }
                }

and so I might achieve things like this:

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

So far, when I alert out 'a' above, it alerts out that it is in fact a [object HTMLDivElement], so it all seemed fine - but I can't access properties on 'a', like nodeName.

Is what I am doing possible? Is it wrong? If I should be able to access properties on the object's key reference then please let me know and I'll write up a sample page.

cheers.

Similar to this SO question, I would like to use HTML nodes as keys in an object (not an array).

Example:

var _hotspots = {
                 [object HTMLDivElement] : { someProps:[1,2,3] },
                 [object HTMLDivElement] : { someProps:[1,2,3] }
                }

and so I might achieve things like this:

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

So far, when I alert out 'a' above, it alerts out that it is in fact a [object HTMLDivElement], so it all seemed fine - but I can't access properties on 'a', like nodeName.

Is what I am doing possible? Is it wrong? If I should be able to access properties on the object's key reference then please let me know and I'll write up a sample page.

cheers.

Share Improve this question edited May 23, 2017 at 12:10 CommunityBot 11 silver badge asked Jun 2, 2011 at 1:47 danjahdanjah 3,0592 gold badges33 silver badges48 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 7

It's now possible to do this with Map or Set objects, but a Map is more appropriate if you want to store key value pair, such as a regular object.

You could still add node as key with regular objects, but the problem is that the node is converted to a string, because objects can only store keys as strings, this means that the object can't distinguish unique nodes that have identical attributes/structure.

The reason Map works is because its keys can be any value, including functions, objects, or any primitive.

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));
<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>

You can also use WeakMap and WeakSet to add node as keys. Using Map/Set, to store elements poses a potential memory issue once elements are removed from DOM, because they are still held in Map/Set and are not garbage collected. When using WeakMap/WeakSet, if no other references to those elements stored in those objects exist, those elements will be garbage collected.

The keys of JavaScript objects are always character. You could store the id as the key and then retreive the element in your function.

You could use my own jshashtable, which accepts any object as key, but if it's not a problem for you to give all your elements an id then I'd remend using an object with element IDs as keys, since that will be the simplest and most performant solution.

本文标签: javascriptStoring an HTML node as key in an *object*Stack Overflow