The Order of Javascript Object Keys
Anthony Frehner
Posted on September 2, 2020
Trivia time! What does the following array look like?
Object.keys({
2: true,
1: true,
'00': true,
'b': true,
'a': true,
'3': true,
})
Answer (click to see)
[ "1", "2", "3", "00", "b", "a" ]
So what exactly is going on?? Here are the ordering rules:
- 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) - Strings come second, and they are ordered within themselves by insertion order
- 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'
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.
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
Posted on September 2, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.