0

I have some strange behavior in JavaScript that I can not understand. For example, we have an object assigned to a variable with string keys in unordered fashion like this

TestObj = {"16":"Bartram Santora","20":"Steffane MacCaffrey","26":"Rozella Dusey","21":"Diego Smartman","28":"Hans Handling","29":"Nonie Gronous"};

It can be seen that index "21" comes after the "26" but when the code executed in Firefox or Chrome console we get an ordered results back like this.

{"16": "Bartram Santora","20": "Steffane MacCaffrey","21": "Diego Smartman","26": "Rozella Dusey","28": "Hans Handling","29": "Nonie Gronous"}

And this is not just shown in consoles, I iterated over the object and outputted in HTML and it is actually ORDERED.

So I cannot get it, why browsers order the UNORDERED objects and treat them like an array. I need the exact unordered list that I get from the server. I do understand that there are indexes that can be casted as numbers not just usual string keys but this is an object not an array.

Does this behavior have some logic behind it or this is just a bug?

Ben Aston
  • 45,997
  • 54
  • 176
  • 303
gagnav
  • 28
  • 4
  • 1
    Object order is not guaranteed, I suspect it's up to the browser on how to interpret it. Chrome and firefox engines may detect that the keys are all numeric, and order then as such. – Sterling Archer Mar 11 '20 at 16:35
  • Also, if you need an object to be in a certain order, you shouldn't use an object – jpthesolver2 Mar 11 '20 at 16:45

1 Answers1

1

If you want an ordered list of values, use an Array or a Map, not a plain object.

The latest JavaScript specification (ES 2020) defines a consistent enumeration order for all operations that enumerate an object.

Prior versions of the specification only defined the enumeration order only for some operations.

The latest spec is really an encoding of behavior that all modern browsers already implemented.

The enumeration order is:

  1. Own properties that are array indexes,1 in ascending numeric index order
  2. Other own string properties, in ascending chronological order of property creation
  3. Own Symbol properties, in ascending chronological order of property creation

This is why you are seeing the behavior you are seeing.

Example:

const o = { z: 'this is z', 2: 'this is 2', 3: 'this is 3', ['1.0']: 'this is 1.0' }

console.log('JSON: ', JSON.stringify(o, null, 2))

for(let [k,v] of Object.entries(o)) console.log(v)

1 An array index is a String-valued property key that is a canonical numeric String2 whose numeric value i is an integer in the range +0 ≤ i < 232 - 1.

2 A canonical numeric String is a String representation of a Number that would be produced by ToString, or the string '-0'. So for instance, '012' is not a canonical numeric String, but '12' is.

Ben Aston
  • 45,997
  • 54
  • 176
  • 303