Chrome re-ordering object keys if numerics, is that normal/expected

Chrome re-ordering object keys if numerics, is that normal/expected

I noticed that certain code that evaluates some shoe sizes for an e-commerce site and outputs them on screen is messing up the order in Chrome.

JSON given can be:

  "7": ["9149", "9139", "10455", "17208"],
  "7.5": ["9140", "9150", "10456", "17209"],
  "8": ["2684", "9141", "10457", "17210"],
  "8.5": ["9142", "10444", "10458", "17211"],
  "9": ["2685", "9143", "10459", "17212"],
  "9.5": ["10443", "9144", "10460", "17213"]

...which increments sizes in halves.

Upon conversion into an object and iterating though the keys, the natural order is being respected and they come out as:

7, 7.5, 8, 8.5 etc.

But in Chrome only, keys that 'look' like round numbers ALWAYS come out of the object first, so output of a for... in loop is:

7, 8, 9, 7.5, 8.5, 9.5 ...

Object.keys(sizes); // ["7", "8", "9", "7.5", "8.5", "9.5"]

Here is the test case:

It's only affects whole numbers, seems like Webkit / Blink have an optimisation that prefers Object properties that are numeric, maybe it's to do with Branch Prediction or whatever.

If you prefix the object keys with any character, the order remains unaffected and works as intended - FIFO

I think I recall reading that there are no guarantees on the order of properties of an object but at the same time, this is annoying to the extreme and would cause a considerable amount of effort in fixing it for chrome users alone.

Any ideas? is this likely a bug that will get fixed?

edit additionally, I have now discovered this as an issue on the v8 bug tracker:

Looks like Blink don't want to fix this and will remain the only browser that will do it.

update whatever hash table optimisation webkit/blink had, has now made its way into gecko (FF 27.0.1) - results in 7,8,9,7.5,8.5,9.5. applying _ before the keys returns the correct / expected order.

update 2017 People are still upvoting and editing this so - It does NOT appear to affect Map / WeakMap, Set etc (as demonstrated by updated main example)

It's the way v8 handles associative arrays. A known issue Issue 164 but it follows the spec so is marked 'working as intended'. There isn't a required order for looping through associative arrays.

A simple workaround is to precede number values with letters e.g: 'size_7':['9149','9139'] etc.

The standard will change in the next ECMAScript spec forcing [chrome] developers to change this.

Chrome re-ordering object keys if numerics, is that normal/expected, Chrome re-ordering object keys if numerics, is that normal/expected. I noticed that certain code that evaluates some shoe sizes for an e-commerce site and  Open the Chrome Task Manager: Shift + Esc: Set focus on the first item in the Chrome toolbar: Shift + Alt + t: Set focus on the rightmost item in the Chrome toolbar: F10 : Switch focus to unfocused dialog (if showing) and all toolbars: F6: Open the Find Bar to search the current page: Ctrl + f or F3: Jump to the next match to your Find Bar

It would appear that Chrome is treating the integer string as if it were a numeric type when used as an index/property name.

I think relying on the Javascript implementation to preserve the order of what, in some cases, is object properties, and in other cases (certainly with chrome) array indices, is demonstrably an unsafe approach and order of enumeration is probably not defined in the spec. I would suggest adding an additional property to the JSON that indicates a sort order:


164 - Wrong order in Object properties interation - v8, But this standart doesn't specify that numeric key will be sorted on any object (​Array on many pages that used to work normally, I'm suggesting people to use firefox. than Chrome, which does reordering on object (for performance reasons. People who expect key-value objects to preserve order of keys are bad coders. Teams. Q&A for Work. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information.

When iterating over the properties of an object, the order is specified in the ECMAScript specification as being undefined and any order you may have observed in some environment should not be relied upon. If you need order, use an Array.

Item order is inverted in Chrome · Issue #45 · swisnl/jQuery , Both IE and Firefox show the items in the order they are declared. /chrome-re-​ordering-object-keys-if-numerics-is-that-normal-expected - even pointing you to  WebElement is highlighted What do you see instead? Exception "org.openqa.selenium.WebDriverException: Object.keys is not a function" Selenium version: java 2.28 OS: Win 7 x64 Browser: Firefox Browser version: 3.6.28 Also it's working fine on version 2.26. I have attached log from my Eclipse env. Reported by Valery.Khromenkov on 2012-12-28 12:51:22

They're being treated as strings because they are strings. My best suggestion would be to use the same "precision" in all your keys.

  "7.0": ["9149", "9139", "10455", "17208"],
  "7.5": ["9140", "9150", "10456", "17209"],
  "8.0": ["2684", "9141", "10457", "17210"],
  "8.5": ["9142", "10444", "10458", "17211"],
  "9.0": ["2685", "9143", "10459", "17212"],
  "9.5": ["10443", "9144", "10460", "17213"]

So, "8.0" instead of "8", etc.

Even then, there are no guarantees, but it is more likely that they'll come out in the same order.

For a better guarantee, perform a sort based on the keys, putting the values into an array in the sorted order.

Object initializer, An object initializer is a comma-delimited list of zero or more pairs of property expected output: 42 Values of object properties can either contain primitive data types or In JSON the values can only be strings, numbers, arrays, true , false Computed property names, Chrome Full support 47, Edge Full  Plain objects also support similar methods, but the syntax is a bit different. Object.keys, values, entries. For plain objects, the following methods are available: Object.keys(obj) – returns an array of keys. Object.values(obj) – returns an array of values. Object.entries(obj) – returns an array of [key, value] pairs.

I don't think you can call this a bug. Like you say yourself, there is no garantee on how the properties of an object are sorted.

Property accessors, Property accessors provide access to an object's properties by using expected output: "Mario". 7 If you use a method for a numeric literal, and the numeric literal has Property accessors, Chrome Full support 1, Edge Full support 12 TypeError: invalid Array.prototype.sort argument · TypeError: invalid  The Object.keys() method returns an array of a given object's own enumerable property names, iterated in the same order that a normal loop would.

Popular Science, THE FUTURE OF THE BODY DIAGNOSIS BRAINPOWER REPRODUCTION THEMEDICINE CABINET STRENGTH Kidneys and lungs built to order in the lab. 18 javascript functions and arguments object, is there a cost involved Mar 16 '11 16 Programmatically fired events not working with event delegation Apr 22 '10 15 MooTools - How to use getSelected() Jul 27 '10

Entity Property Reference, The data values associated with an entity consist of one or more properties. a property with values of mixed types, Datastore uses a deterministic ordering based JsonProperty, Value is a Python object (such as a list or a dict or a string​) that is This is particularly useful for repeated properties for which you expect many  (5 replies) I have a use case in which I want to limit the scope of the method Marionette.Layout.$ to not match results in any layout regions' current views. I basically solved the problem as follows.

Migrating scripts to the V8 runtime | Apps Script, If you have an existing script using the Rhino runtime and want to make To make the V8 version available to users, you must re-publish the script The default behavior for an array is to return keys of all properties, use forof since // forin doesn't expect an iterable. for (var item of year: 'numeric', This is a problem for all chromium based browsers, but the above steps won't work in other derivatives like Vivaldi nor on Linux machines. For other chromium browsers users should use Firefox to go through the keygen process.