JavaScript…
there comes a time in every developer’s life when he wishes to be able to use a Hash in JavaScript like he can use a Hash in Ruby, you know, easily. This usually comes up when implementing A* or some other crazy graph search algorithm.
The problem: JavaScript objects make great Hashes for String and Number keys, but not for Object keys. Some QUnit tests highlight the problem readily.
test("Hash sux?", function() {
var x = {};
var y = {name: "My Cool Object"};
var barbazfoo = {name: "My Uncool Object"};
x['a'] = true;
x['b'] = true;
equals(x['a'], true);
equals(x['b'], true);
x[y] = y.name;
x[barbazfoo] = barbazfoo.name;
equals(x[y], y.name); // Failed! y.toString == "[object Object]"
equals(x[barbazfoo], barbazfoo.name);
});
Now we have two options as I see it: download (or hand roll) our own Hashtable class that has even more akward syntax, worse performance and clocks in at 5k minified… or implement a toString() method that generates unique strings for each object (of types that we care about).
I opted for the second choice, after coming very close to choosing the first. Now if only there were some magical way to implement a unique toString method for all my objects that might want to end up as hash keys.
(function() {
var id = 0;
/*global GameObject */
GameObject = function(game) {
var self = {
// Empty update by default
update: function() {},
click: function() {},
objectId: '#Object:' + (id++),
toString: function() {
return self.objectId;
}
};
return self;
};
})();
Gerta Rauss: So, we all agree that a closure is the best decision for all involved?
Juno MacGuff: SSHHIT! YES! Closure it up!
Now any GameObject can be used as a key to a hash, and as long as you aren’t going nuts and mixing and matching crazy strings as your keys you should have no collisions, or at least way fewer than 100%. Thanks a heap ‘[object Object]’!.
