这是一个建议:
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 与您的问题中显示的完全一样。
但是,您不能在 js 中使用引用(因此两个空对象在哈希表中看起来是一样的),因为您无法获取它。有关更多详细信息,请参阅此答案:如何获取 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/en/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 ) ); // "value1"
console.log( myMap.get( object2 ) ); // "value2"
带有弱映射垫片的 Jsfiddle 演示:http: //jsfiddle.net/Ralt/HKz3e/9/
但是,弱映射是在 FF 和 Chrome 中实现的(仅当您在 chrome 中启用“Experimental javascript features”标志时)。有可用的垫片,例如:https ://gist.github.com/1269991 。使用风险自负。
您也可以使用Maps
,它们可能更适合您的需求,因为您还需要将原始值(字符串)存储为键。医生,希姆。