Curious about the following two cases:
First:
const key = 2;
const obj = { "2": "stackoverflow" };
obj[key]; //results in "stackoverflow" but the key is 2 and not "2"
Second:
//Vice versa case
const otherKey = "21";
const otherObj = { 21: "youtube" };
otherObj[otherKey]; //results in "youtube" but the key is "21" and not 21
My conclusion:
That since keys should be string and while finding key
(when key is seemingly a number) existence in Javascript objects it does so by type-conversion comparison and not by strict or a string conversion.
Is there more to this why these cases work and am more interested in the how bit of that?
The relevant bits of the standard are
12.3.2.1 Runtime Semantics: Evaluation
MemberExpression:MemberExpression[Expression]
...6. Let propertyKey be ? ToPropertyKey(propertyNameValue).
and
7.1.14 ToPropertyKey ( argument )
Let key be ? ToPrimitive(argument, hint String).
If Type(key) is Symbol, then Return key.
Return ! ToString(key).
In plain English, in object[whatever]
, whatever
is converted to a string, unless it's a symbol
.
Illustration:
let s = Symbol();
let o = {
'12': 1,
'foo': 2,
'true': 3,
[s]: 4
}
console.log(o[6*2])
console.log(o[{toString: () => 'foo'}])
console.log(o[1 === 1])
console.log(o[s])
The behaviour of object initializers is described in 12.2.6.7 and is exactly the same.