有人可以向我解释为什么下面的代码示例报告为真?我会假设像在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]);
答案 0 :(得分:5)
您的对象(JavaScript的哈希表)不使用test1
或test2
的实例,但字符串表示为关键字。由于test1
和test2
都具有相同的字符串表示形式:"[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