Search code examples
javascriptjavascript-objects

Why does a number as key worked for a string key in an Object and vice-versa (Javascript)


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?


Solution

  • 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 )

    1. Let key be ? ToPrimitive(argument, hint String).

    2. If Type(key) is Symbol, then Return key.

    3. 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.