开发者

workaround: javascript dictionary which takes objects as keys

开发者 https://www.devze.com 2023-01-09 15:11 出处:网络
I read a few questions and answers about javascript dictionary implementations, but they don\'t meet my requirements:

I read a few questions and answers about javascript dictionary implementations, but they don't meet my requirements:

  • the dictionary must be able to take objects as keys
  • the values must be accessible by the []-operator

So I came up with the idea to overwrite the valueOf-method in Object.prototype, as follows:

Object.__id__ = 0;
Object.prototype.valueOf = function() {
   if(!this.__id__)
      this.__id__ = ++Object.__id__;
    return "__id__" + this.__id__;
}
Object开发者_如何转开发.prototype.toString = Object.prototype.valueOf;

//test   
var x = {p1: "5"};
var y = [6];
var z = {};
z[x] = "7";
z[y] = "8";
console.log(z[x], z[y]);

I tested this with google-chrome and it seems to work well, but I'm a bit sceptical, whether this will cause some drawbacks, since it was so easy to implement.

Considering that the valueOf method is not used for other purposes in the whole code, do you think there are any disadvantages?


It's an interesting idea. I suggest my jshashtable. It meets your first requirement but not the second. I don't really see the advantage of insisting on using the square bracket property access notation: do you have a particular requirement for it?

With jshashtable, you can provide a hashing function to the Hashtable constructor. This function is passed an object to be used as a key and must return a string; you could use a function not dissimilar to what you have there, without having to touch Object.prototype.

There are some disadvantages to your idea:

  1. Your valueOf method will show up in a for...in loop over any native object;
  2. You have no way determining which keys should be considered equal, which is something you may want to do. Instead, all keys will be considered unique.
  3. This won't work with host objects (i.e. objects provided by the environment, such as DOM elements)


It is an interesting question, because I had so far assumed that any object can be used as an index (but never tried with associative arrays). I don't know enough about the inner workings of JavaScript to be sure, but I'd bet that valueOf is used somewhere else by JavaScript, even if not in your code. You might run into seemingly inexplicable problems later. At least, I'd restrict myself to a new class and leave Object alone ;) Or, you explicitly call your hashing function, calling it myHash() or whatever and calling z[x.myHash()] which adds clutter but would let me, personally, sleep better ;) I can't resist thinking there's a more JavaScript-aware solution to this, so consider all of these ugly workarounds ;)


If you came upon this question looking for a JS dictionary where objects are keys look at Map Map vs Object in JavaScript

0

精彩评论

暂无评论...
验证码 换一张
取 消