JavaScript – Why is object[key] Not Equal to Key if Key is an Object?

javascript

var a = new Object;
var b = new Object;
var c = new Object;

c[a] = a;
c[b] = b;

console.log(c[a] === a);

I tested the code above and get false. If I try console.log(c[a] === b), then true is printed.

Why?

Best Answer

The problem here has to do with how an Object's keys are set. From MDN:

Parameters

nameValuePair1, nameValuePair2, ... nameValuePairN

  • Pairs of names (strings) and values (any value) where the name is separated from the value by a colon.

value

  • Any value.

An object's values can be accessed (via the appropriate key) in three ways:

var o = {};
var key = "fun";

// method 1:
o[key]    = "the key will be equal to `key.toString()"
// method 2:
o.key     = "the key will be equal to 'key'"
// method 3:
o["key2"] = "the key will be equal to `key2`"
/*
{
    "fun" : "the key will be...",    // method 1
    "key" : "the key will be...",    // method 2
    "key2": "the key will be..."     // method 3
}
*/

When using bracket notation, you need to mind the gap...between the brackets! Objects set their keys and values using the toString method, unless they're passed a string (then there's no point in toString). When using the dot notation, they use .key as the key.

Let's look at your case:

var a = {}
  , b = {}
  , c = {}
  ;

c[a] = a;
// `a` is not a string, and we're using brackets, so the key
// will be equal to `key.toString()`:
// a.toString() === "[object Object]"
// Try the following in your console: `{}.toString()`
// Note how this is different from console.log({}), since
// the console exposes your object (that's why the dev console is useful)
// c is now: `{ "[object Object]" : a }`

c[b] = b;
// b is also an object, so `b.toString()` is the same as `a.toString()`
// that means c is now `{ "[object Object]" : b }`

assert c[a] === a
// a.toString() == b.toString() == "[object Object]"
// and we just noted that c was `{ "[object Object]" : b }`
// so of course this is false
assert c[b] === b
// true because c[b] == b;
assert c["[object Object]"] === b;
// also true
assert c.b === b
// false, since `c` has no "b" key (c.b is `undefined`)
Related Question