Ilya_Gazman Ilya_Gazman - 1 year ago 81
Javascript Question

Javascript HashTable use Object key

I want to create a hash table that gets my Object as his key without converting it to String.

Some thing like this:

var object1 = new Object();
var object2 = new Object();

var myHash = new HashTable();

myHash.put(object1, "value1");
myHash.put(object2, "value2");

alert(myHash.get(object1), myHash.get(object2)); // I wish that it will print value1 value2

EDIT: See my answer for full solution

Answer Source

Here is a proposal:

function HashTable() {
    this.hashes = {};

HashTable.prototype = {
    constructor: HashTable,

    put: function( key, value ) {
        this.hashes[ JSON.stringify( key ) ] = value;

    get: function( key ) {
        return this.hashes[ JSON.stringify( key ) ];

The API is exactly as shown in your question.

You can't play with the reference in js however (so two empty objects will look like the same to the hashtable), because you have no way to get it. See this answer for more details: How to get javascript object references or reference count?

Jsfiddle demo:

However, for the unique side of things, you could play with the original objects, like in this way:

function HashTable() {
    this.hashes = {}, = 0;

HashTable.prototype = {
    constructor: HashTable,

    put: function( obj, value ) { =;
        this.hashes[ ] = value;;

    get: function( obj ) {
        return this.hashes[ ];

Jsfiddle demo:

This means that your objects need to have a property named id that you won't use elsewhere. If you want to have this property as non-enumerable, I suggest you take a look at defineProperty (it's not cross-browser however, even with ES5-Shim, it doesn't work in IE7).

It also means you are limited on the number of items you can store in this hashtable. Limited to 253, that is.

And now, the "it's not going to work anywhere" solution: use ES6 WeakMaps. They are done exactly for this purpose: having objects as keys. I suggest you read MDN for more information:

It slightly differs from your API though (it's set and not put):

var myMap = new WeakMap(),
    object1 = {},
    object2 = {};

myMap.set( object1, 'value1' );
myMap.set( object2, 'value2' );

console.log( myMap.get( object1 ) ); // "value1"
console.log( myMap.get( object2 ) ); // "value2"

Jsfiddle demo with a weakmap shim:

However, weakmaps are implemented in FF and Chrome (only if you enable the "Experimental javascript features" flag in chrome however). There are shims available, like this one: Use at your own risk.

You can also use Maps, they may more suit your needs, since you also need to store primitive values (strings) as keys. Doc, Shim.