rjkaplan
rjkaplan

Reputation: 3428

__hash__ for javascript?

Is there a way to give objects in js custom hashes, just as overriding

__hash__()

in python let's someone define how a given object is hashed into a dictionary.

My underlying question is: what hash function is used to put js objects into associative arrays, and can I over-ride it?

Upvotes: 2

Views: 508

Answers (2)

Alex Wayne
Alex Wayne

Reputation: 187124

You mean using objects as keys, how do you make sure you access that key again?

The magic method is toString(). Turns out all objects in JS use string keys, and the toString() method is called if it's not a string.

http://jsfiddle.net/udsdT/1/

var objA = {
    data: 'yay',
    toString: function() {
        return 'value_as_key';
    }
};

var objB = {
    data: 'some other totally data thing',
    toString: function() {
        return 'value_as_key';
    }
}


var foo = {};
foo[objA] = 'abc';
foo[objB] = 'def';
foo['value_as_key'] = 'qwe';
foo.value_as_key = 'omg';

foo[objA];           // 'omg'
foo[objB];           // 'omg'
foo['value_as_key']; // 'omg'
foo.value_as_key;    // 'omg'

​​​​​​Usually though, you really don't want to use whole objects as keys. Especially if you dont create your own toString() method, since the default toString() method on basic objects isn't exactly very awesome...

({a:123}).toString() // [object Object]
({b:456}).toString() // [object Object]

var foo = {};
foo[{a:123}] = 'wtf';
foo[{asdf:9876}];       // 'wtf'
foo['[object Object]']; // 'wtf

Upvotes: 7

abarnert
abarnert

Reputation: 365875

In JS, you can't control the hashing, but you don't have to.

Two things are the same if they're equal. The hash is not part of the definition, it's just an implementation detail. Under the covers, two different objects may have the same hash, but they're still different, and the implementation has to deal with that magically (e.g., by using a chaining hash table).

Also, the keys of an object are always strings—the interpreter will stringify the values inside the hash constructor, inside the [], or after the ., rather than storing the actual values, which means that this rarely comes up in the first place.

To give some examples:

function X() {}
x = new X()
y = new Y()
h = {x: 2, y: 3} // h has 2 members, named "x" and "y"

a = (x, y)
b = (x, y)
h[a] = 4
h[b] = 5 // h has 3 members, named "x", "y", and "[object Object]"

Put in Python terms, it's as if dict called __repr__ on keys instead of __hash__ (although this isn't quite 100% accurate), which means you can provide a custom toString method to control equal-ness of different instances of your class.

Upvotes: 1

Related Questions