Reputation: 3428
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
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.
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
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