Understanding how javascript hashtables work
Could anyone explain to me why the code sample below reports true? I would have assumed that like in C# the 开发者_JAVA技巧instance of Test1 != instance of Test2.
Update: So I think I will go with some unique identifier stored in the base of both Test1 and Test2.
function Test1() { };
function Test2() { };
var test1 = new Test1();
var test2 = new Test2();
var dict = new Array();
dict[test1] = true;
alert(dict[test2]);
Your object (JavaScript's hashtable) is not using the instance of test1
or test2
, but the string representation, as a key. Since both test1
and test2
have the same string representation: "[object Object]"
, the true
value is associated with that key.
Try doing something like below instead:
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]);
Keys in 'hashtables' (objects, basically) are always strings. So anything you add will be converted to a string.
new Test1();
returns a instance of Test1
. Converted as a string, this is:
"[object Object]"
The same goes for Test2
. So in fact, when storing true
under the key of new Test1()
as a string, you are working with the exact same record as the one by obtaining with the key new Test2()
as a string. In other words,
(new Test1()).toString() == (new Test2()).toString();
The actual object is therefore simply:
{
"[object Object]": true
}
A solution is overwriting .toString()
like this:
Test1.prototype.toString = function() { return "Test1" };
Test2.prototype.toString = function() { return "Test2" };
Then dict[test1]
will be stored as dict['Test1']
and dict[test2]
as dict['Test2']
, which allows you to differ between them. Still, manually setting dict['Test1']
would overwrite things. As far as I know, there is no way to assign an object as a key.
Javascript objects aren't exactly hashtables; they're actually objects with string keys.
When you use an object as a key, the object is converted to a string by calling toString()
.
toString()
will return the same string for all custom classes (unless you create your own toString
), so they end up using the same key.
First: Use arrays only for numerical keys. For anything else use objects.
Property names can only be strings. Anything else is converted to its string representation. In case of objects, this is [object Object]
or whatever toString()
returns.
Which means, that if you want to make both objects distinguishable, you have to override this method and let it return something which is unique to each instance.
This question might help you: Hash/associative array using several objects as key
精彩评论