理解JavaScript哈希表的工作原理

5

有人能解释一下为什么下面的代码示例报告 True 吗?我本来以为 Test1 的实例与 Test2 的实例不同,就像在 C# 中一样。

更新:所以我想我会使用存储在 Test1 和 Test2 基类中的某些唯一标识符。

function Test1() { };

function Test2() { };

var test1 = new Test1();

var test2 = new Test2();

var dict = new Array();

dict[test1] = true;

alert(dict[test2]);

谢谢大家的回复。我已经给你们所有人点赞了。 - Oliver Weichhold
我提供了一个答案,展示了如何使用多个对象作为键来创建哈希/关联数组(并不是说这是唯一或最好的方法)。 - Felix Kling
4个回答

5

你的对象(JavaScript的哈希表)使用的是字符串表示法作为键,而不是使用test1test2实例。由于test1test2都具有相同的字符串表示法:"[object Object]", 因此true值与该键相关联。

尝试使用以下代码:

function Test1(id) { this.id=id };

function Test2(id) { this.id=id };

var test1 = new Test1('1'); 
var test2 = new Test2('2'); 
var dict = {};

dict[test1.id] = true;

console.log(dict[test1.id]);

好的,那我需要改变什么才能让它按照我想要的方式工作呢? - Oliver Weichhold
function Test1(id) { this.id=id };function Test2(id) { this.id=id };var test1 = new Test1('1'); var test2 = new Test2('2'); var dict = new Array();dict[test1.id] = true;console.log(dict[test1.id]); - Hyangelo
1
@Oliver 如果你正确设置了对象,你可以使toString返回任何你想要的内容。此外,你应该停止用C#的思维方式来考虑Javascript - 除了语法之外它们并不相似。 - dtanders

4

'哈希表'中(基本上是对象),键总是字符串。所以,任何你添加的内容都将被转换为字符串。

new Test1();

返回一个 Test1 实例。转换成字符串,即为:

"[object Object]"

同样的情况也适用于Test2。因此,实际上当您将true作为字符串存储在new Test1()键下时,您正在处理与使用new Test2()键获取的记录完全相同的记录。换句话说,
(new Test1()).toString() == (new Test2()).toString();

因此,实际对象只是:

{
 "[object Object]": true
}

一种解决方法是像这样覆盖.toString()
Test1.prototype.toString = function() { return "Test1" };
Test2.prototype.toString = function() { return "Test2" };

那么dict[test1]将被存储为dict['Test1']dict[test2]将被存储为dict['Test2'],这使您可以区分它们。但是,手动设置dict['Test1']将覆盖其他内容。据我所知,没有办法将对象指定为键。


好的,那么解决这个问题的唯一机会就是让Test1和Test2都实现一些独特的标识属性。 - Oliver Weichhold
@Oliver Weichold:你也可以重写 toString 方法。让我来编辑一下。 - pimvdb

3

Javascript对象并不完全是哈希表,它们实际上是具有字符串键的对象。

当您将对象用作键时,会通过调用toString()将对象转换为字符串。
toString()对于所有自定义类都返回相同的字符串(除非您创建自己的toString),因此它们最终使用相同的键。


2

首先: 只使用数组来作为数字键。对于其他类型的内容,请使用对象。

属性名只能是字符串形式。任何其他类型都会被转换成它的字符串表示形式。对于对象,这通常是[object Object]或者是toString()返回的结果。

这意味着,如果你想使每个对象都有所区别,就需要重写toString()方法并让它返回某个独特的值。

这篇文章可能可以帮助你: Hash/associative array using several objects as key


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接