2

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?

ambianBeing
  • 3,449
  • 2
  • 14
  • 25

3 Answers3

2

What happens here is something called type coercion, where a value of one type is converted to some other type for doing some operation using said value.

Since objects in Javascript store keys and values, and the keys are stored as strings, when you provide a numeric value as the key to the object, it is coerced to a string and then looked up in the object.

It'd be a little clearer if we took the example of an array. Arrays store values at indexes, which are numeric. So if we have var a = [4, 3, 5], looking up the value at index 2 using a a[2] and a["2"] would give you the same result 5, since the string "2" is coerced to a number type to support the lookup operation in the array.

Hope that helps.

Akash Srivastav
  • 756
  • 5
  • 15
  • 2
    Arrays' indexes are strings as well. In fact, Arrays don't treat indexes in any special way. – georg Oct 12 '19 at 21:06
  • See [Is JavaScript array index a string or an integer?](https://stackoverflow.com/q/27537677/1048572) – Bergi Oct 12 '19 at 21:07
  • They do, actually. If we assign some array and later add another value at a much larger new index, the length property will show the number one greater than the largest we just used. That said, since everything in JS is an object we CAN add properties to arrays as well, same as we can for other objects. – Akash Srivastav Oct 12 '19 at 21:08
  • The exotic behaviour of the `.length` property doesn't matter here. Semantically (i.e. ignoring runtime optimisations), array indices are strings like all other property names. – Bergi Oct 12 '19 at 21:10
2

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.

georg
  • 211,518
  • 52
  • 313
  • 390
0

From MDN Docs here

Property names must be strings. This means that non-string objects cannot be used as keys in the object. Any non-string object, including a number, is typecasted into a string via the toString method.

So, basically the keys are type coerced to strings even if they are numbers.

const object = { 21 : 'test', '21': 'message' };

console.log(object)
Dhananjai Pai
  • 5,914
  • 1
  • 10
  • 25
  • 6
    This has nothing to do with JSON – charlietfl Oct 12 '19 at 20:46
  • 2
    JSON was created based on javascript objects ....not the other way around – charlietfl Oct 12 '19 at 20:49
  • @DhananjaiPai But here I am not using `JSON.stringify` and I am pretty sure finding `key` existence would not involve atleast converting it by `JSON.stringify`. – ambianBeing Oct 12 '19 at 20:55
  • I was just saying that Javascript objects store keys as strings and do not differentiate between numbers and strings since JSON was modelled as a serialization mechanism for Javascript Objects and would have factored for "numeric" keys if it was already a language feature! – Dhananjai Pai Oct 12 '19 at 20:57
  • 1
    @ambianBeing Any mention of JSON in this answer is completely irrelevant. It has nothing to do with how the javascript engines manage objects – charlietfl Oct 12 '19 at 20:57