Could anyone explain to me why the code sample below reports true? I would have assumed that like in C# the 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]);
A hash function is a method or function that takes an item's key as an input, assigns a specific index to that key and returns the index whenever the key is looked up. This operation usually returns the same hash for a given key. A good hash function should be efficient to compute and uniformly distribute keys.
A JavaScript Object is an example of a Hash Table because data is represented a key/value pairs. A hashing function can be used to map the key to an index by taking an input of any size and returning a hash code identifier of a fixed size.
Hash tables let us implement things like phone books or dictionaries; in them, we store the association between a value (like a dictionary definition of the word "lamp") and its key (the word "lamp" itself). We can use hash tables to store, retrieve, and delete data uniquely based on their unique key.
The usable size of a hash table is the number of associations that the table can hold at a given time. If the number of associations in the table exceeds the usable size, the table will automatically grow, increasing the usable size to a new value that is sufficient to hold the associations.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With