>> About anything can be a key in JS. (DomNodes can't, though >> btw, but functions objects etc) > > No, that isn't true, sorry.
No need to be sorry. I stand corrected. My misunderstanding of this nuance stems from having never noticed the toString function defined here ... toString: function(){ return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String }, but now it makes absolute sense. (I've only even been using it to store refs to instances of these thingers in objects and compare them later.) Thanks for taking the time to clarify. Regards, Peter Higgins > Object keys in JavaScript are strings only, nothing else. >> var bar = { a:"b", c:"d" }; >> var bar2 = [1,2,3,4]; >> var foo = {}; >> foo[bar] = "baz"; >> foo[bar2] = "baz2"; >> >> if(bar in foo){ console.log(foo[bar]); } // baz >> if(bar2 in foo){ console.log(foo[bar2]); } // baz2 > > What you're observing is that JS will convert any object to a string when > necessary, by calling that object's toString() method. > > The reason your example works is that the two properties you're adding have > different string representations, because one is an object and the other is > an array. Let's look at it more closely: > > var bar = { a:"b", c:"d" }; > var bar2 = [1,2,3,4]; > var foo = {}; > foo[bar] = "baz"; > foo[bar2] = "baz2"; > > for( var key in foo ) { console.log( typeof key, key ); } > // string [object Object] > // string 1,2,3,4 > > Now try it with two different *object* keys instead of an object and an > array > > var bar = { a:"b", c:"d" }; > var bar2 = { w:"x", y:"z" }; > var foo = {}; > foo[bar] = "baz"; > foo[bar2] = "baz2"; > > for( var key in foo ) { console.log( typeof key, key, foo[key] ); } > // string [object Object] baz2 (only one - oops!) > > Because bar and bar2 have identical string representations - '[object > Object]' - only one property is added to the foo object. > > DOM nodes do work the same way - because they also have string > representations. But you'll run into the same problem, because, for example, > every DIV has the same string representation '[object HTMLDivElement]'. > > As another example, here's an object with a custom toString method. Note > that after adding the property, we can reference it using the name that > toString returned: > > a = { toString:function() { return 'foo'; } }; > b = {}; > b[a] = 'test'; > console.log( b.foo ); // 'test' > > And one with *no* toString method: > > a = { toString:null }; > b = {}; > b[a] = 'test'; // TypeError: can't convert a to string > > All this is quite different from, say, Ruby, where any object *can* be used > as a hash key: > > irb(main):001:0> a = { 'a' => 'b', 'c' => 'd' } > => {"a"=>"b", "c"=>"d"} > irb(main):002:0> b = { 'a' => 'b', 'c' => 'd' } > => {"a"=>"b", "c"=>"d"} > irb(main):003:0> c = { a => 'aaa', b => 'bbb' } > => {{"a"=>"b", "c"=>"d"}=>"bbb", {"a"=>"b", "c"=>"d"}=>"aaa"} > irb(main):004:0> c[a] > => "aaa" > irb(main):005:0> c[b] > => "bbb" > > Note that the a and b hashes are two distinct objects even though their > content is similar, and each one can be used as a separate hash key. > > -Mike > >> From: pete higgins >> >> About anything can be a key in JS. (DomNodes can't, though >> btw, but functions objects etc) >> >> var bar = { a:"b", c:"d" }; >> var bar2 = [1,2,3,4]; >> var foo = {}; >> foo[bar] = "baz"; >> foo[bar2] = "baz2"; >> >> if(bar in foo){ console.log(foo[bar]); } // baz >> if(bar2 in foo){ console.log(foo[bar2]); } // baz2 > >