The Order of Javascript Object Keys

frehner

Anthony Frehner

Posted on September 2, 2020

The Order of Javascript Object Keys

Trivia time! What does the following array look like?

Object.keys({
  2: true, 
  1: true,
  '00': true,
  'b': true,
  'a': true,
  '3': true,
})
Enter fullscreen mode Exit fullscreen mode

Answer (click to see)
[ "1", "2", "3", "00", "b", "a" ]
Enter fullscreen mode Exit fullscreen mode

So what exactly is going on?? Here are the ordering rules:

  1. Numbers are ordered first, and they are ordered within themselves from smallest to largest as long as they are >=0 (see below for more details)
  2. Strings come second, and they are ordered within themselves by insertion order
  3. Symbols come last, and they are ordered within themselves by insertion order (note that we didn't use symbols in this example)

But wait, why did '3' come before '00' if strings are ordered within themselves by insertion order?

Well, turns out that JS will see if your string can be converted to a number - if it can, then it will order it with the numbers and not the strings.

And what about '00'? Apparently it converts it to a new number, then does something similar to toString() on new number, and compares that new string with the original string.

If they match, then it can be lumped in with the numbers. If it doesn't match, then it's a string.

const originalString = '00'
const stringToNumber = Number(originalString)
const matchesOriginalString = stringToNumber.toString() === originalString // false: '0' !== '00'
Enter fullscreen mode Exit fullscreen mode

Pretty clear, huh? :P

Thanks to this article for helping https://www.stefanjudis.com/today-i-learned/property-order-is-predictable-in-javascript-objects-since-es2015/


Here's the wording from the spec:

Numbers

For each own property key P of O such that P is an array index, in ascending numeric index order, Add P as the last element of keys.

i.e. insert numerical keys first in ascending order

Strings

For each own property key P of O such that Type(P) is String and P is not an array index, in ascending chronological order of property creation, Add P as the last element of keys.

i.e. insert string keys in order of creation as long as they're not an array index. So what's that?

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.21) and whose numeric value is either +0 or a positive integer ≤ 253 - 1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232 - 1.

source for array index

i.e. a string key that is a canonical numeric string and greater than +0

so... what's a canonical numeric string?

[A canonical numeric string is an] argument converted to a Number value if it is a String representation of a Number that would be produced by ToString, or the string "-0".

source for canonical numeric string
i.e. if that string is the same as any number that is toString()

Symbols

For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation, Add P as the last element of keys.

i.e. insert symbol keys in order of creation

💖 💪 🙅 🚩
frehner
Anthony Frehner

Posted on September 2, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

The Order of Javascript Object Keys
javascript The Order of Javascript Object Keys

September 2, 2020