了解javascript哈希表的工作原理

时间:2011-08-19 19:31:53

标签: javascript

有人可以向我解释为什么下面的代码示例报告为真?我会假设像在C#中一样,Test1的实例!= Test2的实例。

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

function Test1() { };

function Test2() { };

var test1 = new Test1();

var test2 = new Test2();

var dict = new Array();

dict[test1] = true;

alert(dict[test2]);

4 个答案:

答案 0 :(得分: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]);

答案 1 :(得分:4)

'hashtables'中的键(基本上是对象)总是字符串。因此,您添加的任何内容都将转换为字符串。

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']会覆盖事物。据我所知,没有办法将对象指定为键。

答案 2 :(得分:3)

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

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

答案 3 :(得分:2)

首先:仅将数组用于数字键。其他任何使用对象。

属性名称只能是字符串。其他任何东西都转换为其字符串表示形式。对于对象,这是[object Object]或任何toString()返回。

这意味着,如果您想要使两个对象都可以区分,则必须覆盖此方法并让它返回对每个实例唯一的内容。

这个问题可能会对您有所帮助:Hash/associative array using several objects as key