这里是一个提议:
function HashTable() {
this.hashes = {};
}
HashTable.prototype = {
constructor: HashTable,
put: function( key, value ) {
this.hashes[ JSON.stringify( key ) ] = value;
},
get: function( key ) {
return this.hashes[ JSON.stringify( key ) ];
}
};
这个API与您的问题中所示完全相同。
然而,在 JavaScript 中,您无法使用引用进行操作(因此两个空对象将在散列表中看起来相同),因为您无法获取它。请参见此答案以了解更多细节:如何获取 JavaScript 对象引用或引用计数?
Jsfiddle演示:http://jsfiddle.net/HKz3e/
不过,对于唯一性方面,您可以操作原始对象,像这样:
function HashTable() {
this.hashes = {},
this.id = 0;
}
HashTable.prototype = {
constructor: HashTable,
put: function( obj, value ) {
obj.id = this.id;
this.hashes[ this.id ] = value;
this.id++;
},
get: function( obj ) {
return this.hashes[ obj.id ];
}
};
Jsfiddle演示:http://jsfiddle.net/HKz3e/2/
这意味着您的对象需要有一个名为id
的属性,您不会在其他地方使用它。如果您想将此属性设置为不可枚举,请查看defineProperty
(但它不跨浏览器兼容,即使使用ES5-Shim,在IE7中也无法正常工作)。
这也意味着您在此哈希表中存储的项目数量受到限制。受限于2 53个。
现在,这是“无处可用”的解决方案:使用ES6 WeakMaps。它们正是出于这个目的而设计的:将对象作为键。建议您阅读MDN以获取更多信息:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakMap
但与您的API略有不同(它是set
而不是put
):
var myMap = new WeakMap(),
object1 = {},
object2 = {};
myMap.set( object1, 'value1' );
myMap.set( object2, 'value2' );
console.log( myMap.get( object1 ) );
console.log( myMap.get( object2 ) );
这是一个包含 WeakMap polyfill 的 JsFiddle 演示:http://jsfiddle.net/Ralt/HKz3e/9/
但是,WeakMap 已在 Firefox 和 Chrome 中实现(仅当您在 Chrome 中启用“实验性 JavaScript 特性”标志时才可用)。有可用的 shims,例如此处提供的: https://gist.github.com/1269991。请自行决定是否使用。
您也可以使用 Maps
,它们可能更适合您的需求,因为您需要将原始值(字符串)作为键存储。 有关文档和 shim,参见:Doc,Shim。