0

I figured every new instance of an HTML element would be it's own distinct object, but hash tables are telling me differently. If I do: document.createElement("button") === document.createElement("button") I get the expected result of false , but if I do:

let hash = {
    [document.createElement("button")]: "choice 1",
    [document.createElement("button")]: "choice 2"
}

console.log(hash);

then the result is: {[object HTMLButtonElement]: 'choice 2'}, meaning the second button element overwrote the first button element even though they're supposedly different values. Does anyone know why that is? Can we not use elements as distinct keys in a hash table? If so, is there an alternate way of achieving what I have above?

  • 1
    How would you hope to retrieve the values? – Pointy Mar 09 '22 at 14:22
  • 2
    Notice the key to the hash is a string. This happens automatically and `toString()` on both elements results in the same key value causing the first to be overridden. – phuzi Mar 09 '22 at 14:22
  • https://stackoverflow.com/questions/3608246/what-is-the-type-of-keys-in-javascript – juzraai Mar 09 '22 at 14:23
  • 4
    Those aren't HTML element **literals**, those are function calls that create element instances, which are objects. What you're putting them in isn't a "hash table," it's an *object*. No, you can't use an object (like an HTML element) as a property key in a JavaScript object. When you try, as you can see, the object is asked to convert itself to a primitive (usually that's a string) and that's used instead. You *can* use an object as the key in a `Map`, though: `let map = new Map([ [document.createElement("button"), "choice 1"], [document.createElement("button"), "choice 2"], ]);` – T.J. Crowder Mar 09 '22 at 14:23
  • JavaScript objects are not (necessarily) "hash tables". They're objects with named properties, and the names are always strings. You can look into the Map class, which allows arbitrary values to be used as keys. – Pointy Mar 09 '22 at 14:23
  • @Pointy - Well, property *names* are always strings, but property *keys* may be string or `Symbol`. :-) (Though even the spec is inconsistent about "name" vs. "key".) – T.J. Crowder Mar 09 '22 at 14:26
  • 1
    @T.J.Crowder oh yea, Symbol. Now that I'm free of IE11 concerns I should start using those more, they fix the ugly hacks that used to be necessary for some getter/setter patterns and other lovely things. – Pointy Mar 09 '22 at 14:36
  • 1
    @T.J.Crowder Thank you guys for the info! I'm still new to JavaScript and I'm used to similar looking data structures in other languages behaving differently. This was a huge help. – WillWillington Mar 09 '22 at 14:41
  • @Pointy - Yeah -- Symbol or private members (since Symbols are still discoverable). :-) – T.J. Crowder Mar 09 '22 at 14:41

0 Answers0