4

While working on another problem, I was misled by the fact that Chrome (and perhaps other browsers) somehow magically sorts keys of an object when outputting it to the console:

let inputs = ["XMl", "SFJ", "dTg", "amN"];
let promises = {};

for (let val of inputs) {
   let p = new Promise(
      (resolve) => setTimeout(resolve, 500 + Math.random() * 1500, "new:" + val)
   );
   promises[val] = p
}

console.log(promises)
Promise.allSettled(Object.values(promises)).then((res) => console.log(res))

Now the browser (Chrome) shows me:

enter image description here

So, there is a difference between the expanded and the collapsed output. Is that standard behavior? Where does this come from?

Philipp Imhof
  • 204
  • 1
  • 7
  • You can just do `let promises = {}` for the issue you mention. Nothing specific to arrays. It's misleading. – adiga Jan 25 '22 at 14:30
  • Thanks for the comments. I added the `let` (which was there in the original code) and changed to `let promises = {}`. – Philipp Imhof Jan 25 '22 at 14:33
  • @adiga However, the output is still different for the collapsed and the expanded form. – Philipp Imhof Jan 25 '22 at 14:33
  • 1
    @PhilippImhof yes. The question is now specific to order of keys and not associative arrays – adiga Jan 25 '22 at 14:34
  • The expanaded order simply is alphabetical... with the capitals first. – Louys Patrice Bessette Jan 25 '22 at 14:35
  • @LouysPatriceBessette Yes, I noticed that. But WHY is this the case? And is this standardized in any way? Do other browsers do the same? The internal console of JS Fiddle seems to sort them in alphabetical order, but lower case letters first. – Philipp Imhof Jan 25 '22 at 14:38
  • 1
    I guess this is ordered to help you find a specific key easilly... I don't know about any standard for this. – Louys Patrice Bessette Jan 25 '22 at 14:41
  • [question from when it changed from alphabetical to property order](https://stackoverflow.com/questions/59560322/how-can-i-make-object-properties-in-console-logobj-display-alphabetically-in-c), apparently it changed back? I must admit i initially misread the question, sorry. – ASDFGerte Jan 25 '22 at 14:48
  • @LouysPatriceBessette True, it obviously is useful and, when I think about it, I normally rely on this when inspecting objects. I think my confusion arises from a point raised by T.J. Crowder: they are not associative arrays, they are objects, so they are shown like objects. – Philipp Imhof Jan 25 '22 at 15:04
  • I've opened a ticket in the bug tracker about this: https://bugs.chromium.org/p/chromium/issues/detail?id=1377264 – Kael Watts-Deuchar Oct 21 '22 at 10:51

1 Answers1

4

Here's a simpler replication of the issue:

const obj = {
    XMl: 1,
    SFJ: 1,
    dTg: 1,
    amN: 1,
};
console.log(obj);

For which I get:

devtools object screenshot with the order described below

The summary seems to be shown in property order (more on that in a moment), but then when displaying the object details Chrome's devtools shows the properties in alphabetical order (including grouping capitals together; it looks very much like the ordering simple < and > would do, rather than localeCompare or similar). Firefox's looks similar.

The first is covered by the JavaScript specification (details here). I don't think there's any standard that covers the second, but if you think about it, alpha order is probably more useful than property order when you're trying to find a property in an object with lots of properties. Property order is complicated and only mostly based on the order in which the properties were created, so it can can seem chaotic. And grouping the capitals together categorizes slightly, given the JavaScript convention that initial capital letters are almost entirely reserved for constructor functions and all caps constants.


Originally you used the term "associative array" instead of object. As I mentioned in a comment, they're really objects, not just associative arrays. If you did want just a basic "map" style name/value pairs thing, that would be a Map and the order of map entries is nice and simple: It's the order the entry was created. If we do the same thing we did above but with a Map, both the summary and the detail show the information in the same order:

const map = new Map([
    ["XMl", 1],
    ["SFJ", 1],
    ["dTg", 1],
    ["amN", 1],
]);
console.log(map);

devtools map object screenshot showing same order in summary and detail

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 2
    Thanks. I guess my confusion (at least partially) arises from a fact you raised in your comment on my question: as they are objects and not associative arrays (like I sometimes say when being sloppy), there is no reason they should be shown in another way than any other object. Obviously, it's more than just semantics in this case. – Philipp Imhof Jan 25 '22 at 15:06
  • 1
    @PhilippImhof - Yeah. If you want a simpler name/value sort of thing, `Map` has a nice simple order -- it's purely the order of insertion. Happy coding! – T.J. Crowder Jan 25 '22 at 16:03