Are objects in JavaScript just HashMaps?

View other answers to this thread
Mark's photo

I thought so, but according to StackOverflow, they're actually not hashmaps in the way that you would typically expect:

  • The key is converted to a string, which isn't what you'd usually think of for hashing (and according to Wikipedia, it isn't, because the result is not fixed-size).

    var q = {}
    q[1] = 42
    console.log(q['1'])  // 42
  • When two objects have the same string representation, there's no further equality checking.

    function P (a) {
      this.a = a
    o1 = new P(1)
    o2 = new P(2)
    var q = {}
    q[o1] = 42
    console.log(q[o2])  // 42

So they're different objects, but the hashmap doesn't notice.

It does seem to use a hashtable (not sure that's a standard or an implementation detail), so it is fast.

You could use your own hashing function and {} use it as a hashmap that way, if you're sure your hashing function yields unique keys (that aren't keywords). Either wrap the hashing function around all map accesses, or overwrite toString (obviously has the side effect over changing the string representation).

Or only use specific types like strings and numbers as keys.

As an additional note, it seems that ECMAScript 6 added special maps, so it seems there was agreement that objects were not, in fact, maps: . It seems this uses reference equality instead, which is the other extreme and treats identical clones as distinct. But JS generally doesn't do object equality properly, so what can you really expect...

Sebastian's photo

The specification defines it only as a collection of string keys.

hashmaps are a sub form of a collection handling keys is a special way.

So it’s up the engine how to implement this collection. Would be interesting how Mozilla, Google and Microsoft have handled this.

Object type is 6.1.7 in the specification

Also numbers are getting converted to strings so technically no numbers as keys. Only strings and Symbols.

Mark's photo

Thanks, I suspected it may be an implementation detail. According to SO, browsers do use hashtables, and it's hard to imagine them using something slower.

As for the last part, I meant you can use integers for indexing, not that they're stored as integer. But still a useful note, since it means that q[1] is the same as q['1'].