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]’!.